KMAdvertisementManager.swift 13 KB

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