KMAdvertisementManager.swift 15 KB

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