KMAdvertisementManager.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. //
  2. // KMAdvertisementManager.swift
  3. // KMAdvertisement
  4. //
  5. // Created by lizhe on 2022/11/23.
  6. // 广告管理
  7. @objcMembers open class KMAdvertisementManager: NSObject {
  8. //单例
  9. @objc public static let manager = KMAdvertisementManager()
  10. @objc public var configuration: KMAdvertisementConfig = KMAdvertisementConfig()
  11. var info: KMAdvertisementInfo = KMAdvertisementInfo()
  12. /**
  13. @abstract 测试模式,默认为false
  14. */
  15. @objc public var debug: Bool = false
  16. /**
  17. @abstract 初始化数据
  18. @param appID 产品名称
  19. @param subscribeType 订阅状态,可单独在configuration设置
  20. @param platform 平台
  21. @return
  22. */
  23. @objc public func initConfig(appName: KMAdvertisementAppNameType,
  24. subscribeType:KMAdvertisementSubscribeType,
  25. platform: KMAdvertisementPlatformType) {
  26. configuration.initParameters(appName: appName, subscribeType: subscribeType, platform: platform)
  27. }
  28. private class InternalImplementation {
  29. fileprivate var privateProperty: String = "Hidden"
  30. fileprivate func internalMethod() {
  31. // 实现细节
  32. }
  33. }
  34. private let internalImplementation = InternalImplementation()
  35. public func publicMethod() {
  36. // 使用内部实现
  37. internalImplementation.internalMethod()
  38. }
  39. }
  40. extension KMAdvertisementManager {
  41. //MARK: request
  42. /**
  43. @abstract 获取数据
  44. @param data 传入参数 类型为KMAdvertisementModel
  45. @return
  46. */
  47. @objc public func fetchData(completion: @escaping (_ data: KMAdvertisementInfo?, _ error:Error?) -> Void) -> Void {
  48. self.fetchDataWithResponseObject { data, responseObject, error in
  49. if completion != nil {
  50. completion(data, error)
  51. }
  52. }
  53. }
  54. @objc public func fetchDataWithResponseObject(completion:@escaping (_ data: KMAdvertisementInfo?, _ responseObject: AnyObject? , _ error:Error?) -> Void) -> Void {
  55. print("开始获取数据")
  56. var version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString").debugDescription
  57. if (version.count == 0) {
  58. version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion").debugDescription
  59. version = version.replacingOccurrences(of: ".", with: "")
  60. }
  61. let urlString = configuration.activityBaseURL() + "/api/advertise-new"
  62. let params: [String:Any] = ["app_name": configuration.appName.string(),
  63. "app_version": version]
  64. //先拿缓存数据 再请求新数据
  65. let cacheData = KMAdvertisementCache.default.readData()
  66. if cacheData.count != 0 {
  67. self.parseData(data: cacheData, isNeedLocalComparison: false) { result in
  68. if result.count != 0 {
  69. info = result.first!
  70. completion(result.first, nil, nil)
  71. }
  72. }
  73. }
  74. unowned let weakSelf = self
  75. KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: params) { [self] task, responseObject, error in
  76. print("正在获取数据")
  77. if (error == nil && responseObject != nil) {
  78. let array = responseObject?["list"] ?? []
  79. if array != nil {
  80. //解析数据
  81. print("开始解析数据")
  82. weakSelf.parseData(data: array as! [NSDictionary], isNeedLocalComparison: true) { data in
  83. print("数据处理完毕")
  84. if data.count != 0 {
  85. info = data.first!
  86. completion(data.first, responseObject, nil)
  87. }
  88. }
  89. } else {
  90. print("解析数据失败array")
  91. completion(nil, responseObject, error)
  92. }
  93. } else {
  94. print("解析数据失败数据不存在")
  95. completion(nil, responseObject, error)
  96. }
  97. }
  98. }
  99. }
  100. extension KMAdvertisementManager {
  101. //MARK: data
  102. /**
  103. @abstract 解析数据
  104. @param data 传入参数 NSDictionary
  105. @param isNeedLocalComparison 是否需要对比本地版本,如果不一样将会刷新
  106. @return KMAdvertisementModel
  107. */
  108. public func parseData(data: [NSDictionary], isNeedLocalComparison: Bool ,completion:(_ result: [KMAdvertisementInfo]) -> Void) -> Void {
  109. //获取缓存数据
  110. var isNeedSave = false
  111. let cacheData = KMAdvertisementCache.default.readData()
  112. var resultArray:[KMAdvertisementInfo] = []
  113. for model in data {
  114. if (!(cacheData.contains(model) && isNeedLocalComparison)) {
  115. if (self.allowLoadData(data: model)) {
  116. let jsonString: String = (model["detail"] as? String) ?? ""
  117. let jsonData: Data = jsonString.data(using: .utf8)!
  118. let dict = try?JSONSerialization.jsonObject(with: jsonData)
  119. let decoder = JSONDecoder()
  120. // decoder.dataDecodingStrategy = .base64
  121. // decoder.keyDecodingStrategy = .convertFromSnakeCase //带下划线命名
  122. decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "+∞", negativeInfinity: "-∞", nan: "NaN")
  123. #if DEBUG
  124. //MARK: 测试使用
  125. var advertisementModel = try! decoder.decode(KMAdvertisementInfo.self, from: jsonData)
  126. if (self.allowLoadContentData(data: advertisementModel)) {
  127. resultArray.append(self.allowLoadItemData(advertisementModel))
  128. isNeedSave = true
  129. }
  130. #else
  131. // MARK: 此处try 使用 ? ,如果数据出问题 advertisementModel将无参数, 测试时使用!
  132. var advertisementModel = try? decoder.decode(KMAdvertisementInfo.self, from: jsonData)
  133. if (advertisementModel != nil) {
  134. if (self.allowLoadContentData(data: advertisementModel!)) {
  135. resultArray.append(self.allowLoadItemData(advertisementModel!))
  136. isNeedSave = true
  137. }
  138. }
  139. #endif
  140. }
  141. }
  142. }
  143. if isNeedSave && isNeedLocalComparison {
  144. KMAdvertisementCache.default.saveData(data: data)
  145. print("已更新本地数据")
  146. } else {
  147. print("不需要更新本地数据")
  148. }
  149. completion(resultArray)
  150. }
  151. func allowLoadData(data: NSDictionary) -> Bool {
  152. var result = false
  153. let status = (data["status"] as? Int) ?? 0
  154. let app_name: String = data["app_name"] as? String ?? ""
  155. if (status == 1 &&
  156. app_name == configuration.appName.string()) {
  157. result = true
  158. }
  159. return result
  160. }
  161. func allowLoadContentData(data: KMAdvertisementInfo) -> Bool {
  162. var result = true
  163. return result
  164. }
  165. // func allowLoadContentData(data: KMAdvertisementModel) -> Bool {
  166. // var result = false
  167. //
  168. // let time: NSInteger = NSInteger(KMAdvertisementTimeStampConversion.getCurrentTimeInterval())!
  169. // let startTime: NSInteger = NSInteger(data.startTime!)!
  170. // let endTime: NSInteger = NSInteger(data.endTime!)!
  171. // let platform = configuration.platform
  172. // let subscribeType = configuration.subscribeType
  173. // let version = data.version ?? "1.0"
  174. // let localVersion = self.getLocalVersion()
  175. // let hidden = data.hidden ?? false
  176. //
  177. // if (time >= startTime &&
  178. // time <= endTime &&
  179. // platform == data.platform &&
  180. // self.compareVersion(nowVersion:localVersion, newVersion: version) &&
  181. // (subscribeType == data.subscribeType || data.subscribeType == .all) &&
  182. // !hidden) {
  183. // result = true
  184. // }
  185. // return result
  186. // }
  187. //过滤item是否显示
  188. func allowLoadItemData(_ data: KMAdvertisementInfo) -> KMAdvertisementInfo {
  189. let advertisement = data.advertisement
  190. advertisement?.content = self.canShow(data: (advertisement?.content)!)
  191. data.advertisement = advertisement
  192. let recommondContent = data.recommondContent
  193. let recommondContentOther = recommondContent?.recommondContentOther
  194. let recommondContentPDFPro = recommondContent?.recommondContentPDFPro
  195. recommondContentOther?.content = self.canShow(data: (recommondContentOther?.content)!)
  196. recommondContentPDFPro?.content = self.canShow(data: (recommondContentPDFPro?.content)!)
  197. recommondContent?.recommondContentOther = recommondContentOther
  198. recommondContent?.recommondContentPDFPro = recommondContentPDFPro
  199. data.recommondContent = recommondContent
  200. return data;
  201. }
  202. func canShow(data: [KMAdvertisementItemInfo]) -> [KMAdvertisementItemInfo] {
  203. var dataArray: [KMAdvertisementItemInfo] = []
  204. for item in data {
  205. let currentTime = Int(NSDate.init().timeIntervalSince1970 * 1000)
  206. if item.show == "1" &&
  207. currentTime > Int(item.startTime ?? "0") ?? currentTime &&
  208. currentTime < Int(item.endTime ?? "0") ?? currentTime {
  209. var canAdd = true
  210. if item.subscriptionType == "1" {
  211. if KMPurchaseManager.manager.state == .subscription {
  212. canAdd = false
  213. }
  214. } else if item.subscriptionType == "2" {
  215. if KMPurchaseManager.manager.state != .subscription {
  216. canAdd = false
  217. }
  218. }
  219. if canAdd {
  220. dataArray.append(item)
  221. }
  222. }
  223. }
  224. return dataArray
  225. }
  226. // + (BOOL)checkAdvertisementValid:(KMRecommondInfo *)info {
  227. // #if DEBUG
  228. // [[NSUserDefaults standardUserDefaults] removeObjectForKey:info.versionKey];
  229. // #endif
  230. // if ([[NSUserDefaults standardUserDefaults] objectForKey:info.versionKey]) {
  231. // return NO;
  232. // }
  233. // if (!info.show) {
  234. // return NO;
  235. // }
  236. // if (info.showType == KMRecommondShowType_Lite) {
  237. // if ([[IAPProductsManager defaultManager] isAvailableAllFunction]) {
  238. // return NO;
  239. // }
  240. // } else if (info.showType == KMRecommondShowType_Pro) {
  241. // if (![[IAPProductsManager defaultManager] isAvailableAllFunction]) {
  242. // return NO;
  243. // }
  244. // }
  245. // return YES;
  246. // }
  247. // func allowLoadItemData(_ data: KMAdvertisementModel) -> KMAdvertisementModel {
  248. // //获取缓存数据
  249. // if (UserDefaults.standard.object(forKey: "KMAdvertisementShowScroll_iOS") == nil) {
  250. // UserDefaults.standard.set([], forKey: "KMAdvertisementShowScroll_iOS")
  251. // }
  252. // let cacheArray: [String] = UserDefaults.standard.object(forKey: "KMAdvertisementShowScroll_iOS") as! [String]
  253. //
  254. // let model = data
  255. // var sections: [KMAdvertisementModelSection] = []
  256. // for section in data.content! {
  257. // var items: [KMAdvertisementModelItem] = []
  258. // for item in section.content! {
  259. // let timeString = KMAdvertisementTimeStampConversion.getCurrentTimeInterval()
  260. // let time: NSInteger = NSInteger(timeString)!
  261. // let startTime: NSInteger = NSInteger(item.startTime ?? timeString)!
  262. // let endTime: NSInteger = NSInteger(item.endTime ?? timeString)!
  263. // let hidden = item.hidden ?? false
  264. //
  265. //// print(hidden ? "隐藏" : "显示")
  266. // if (!hidden &&
  267. // time >= startTime &&
  268. // time <= endTime &&
  269. // !cacheArray.contains(item.productID ?? "")) {
  270. // items.append(item)
  271. // }
  272. // }
  273. // section.content = items
  274. // sections.append(section)
  275. // }
  276. // model.content = sections
  277. // return model
  278. // }
  279. //获取本地版本号
  280. func getLocalVersion() -> String {
  281. var localVersion = ""
  282. if let v: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
  283. localVersion = v
  284. }
  285. return localVersion
  286. }
  287. func compareVersion(nowVersion: String, newVersion: String) -> Bool {
  288. let nowArray = nowVersion.split(separator: ".")
  289. let newArray = newVersion.split(separator: ".")
  290. let big = nowArray.count > newArray.count ? newArray.count : nowArray.count
  291. if big != 0 {
  292. for index in 0...big - 1 {
  293. let first = nowArray[index]
  294. let second = newArray[index]
  295. if Int(first)! < Int(second)! {
  296. return true
  297. }
  298. if index == big - 1 {
  299. if Int(first)! <= Int(second)! {
  300. return true
  301. }
  302. }
  303. }
  304. } else {
  305. return true
  306. }
  307. return false
  308. }
  309. }