KMAdvertisementManager.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. //
  2. // KMAdvertisementManager.swift
  3. // KMAdvertisement
  4. //
  5. // Created by lizhe on 2022/11/23.
  6. // 广告管理
  7. #if os(OSX)
  8. import AppKit
  9. public typealias UIImage = NSImage
  10. public typealias UIView = NSView
  11. public typealias UIButton = NSButton
  12. public typealias UIScrollView = NSScrollView
  13. public typealias UIColor = NSColor
  14. public typealias UIFont = NSFont
  15. public typealias UITextView = NSTextView
  16. public typealias UIImageView = NSImageView
  17. public typealias UIEvent = NSEvent
  18. public typealias UIBezierPath = NSBezierPath
  19. public typealias UITextField = NSTextField
  20. public typealias UIEdgeInsets = NSEdgeInsets
  21. #elseif os(iOS)
  22. import UIKit
  23. public typealias NSImage = UIImage
  24. public typealias NSView = UIView
  25. public typealias NSButton = UIButton
  26. public typealias NSScrollView = UIScrollView
  27. public typealias NSColor = UIColor
  28. public typealias NSFont = UIFont
  29. public typealias NSTextView = UITextView
  30. public typealias NSImageView = UIImageView
  31. public typealias NSEvent = UIEvent
  32. public typealias NSBezierPath = UIBezierPath
  33. public typealias NSTextField = UILabel
  34. public typealias NSEdgeInsets = UIEdgeInsets
  35. #endif
  36. open class KMAdvertisementManager {
  37. //单例
  38. public static let manager = KMAdvertisementManager()
  39. public var configuration: KMAdvertisementConfig = KMAdvertisementConfig()
  40. /**
  41. @abstract 测试模式,默认为false
  42. */
  43. public var debug: Bool = false
  44. /**
  45. @abstract 初始化数据
  46. @param appID 产品名称
  47. @param subscribeType 订阅状态,可单独在configuration设置
  48. @param platform 平台
  49. @return
  50. */
  51. public func initConfig(appName: KMAdvertisementAppNameType,
  52. subscribeType:KMAdvertisementSubscribeType,
  53. platform: KMAdvertisementPlatformType) {
  54. configuration.initParameters(appName: appName, subscribeType: subscribeType, platform: platform)
  55. }
  56. }
  57. extension KMAdvertisementManager {
  58. //MARK: request
  59. /**
  60. @abstract 获取数据
  61. @param data 传入参数 类型为KMAdvertisementModel
  62. @return
  63. */
  64. public func fetchData(completion:@escaping (_ data: [KMAdvertisementModel]?, _ error:Error?) -> Void) -> Void {
  65. var version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString").debugDescription
  66. if (version.count == 0) {
  67. version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion").debugDescription
  68. version = version.replacingOccurrences(of: ".", with: "")
  69. }
  70. let urlString = configuration.activityBaseURL() + "/api/advertise"
  71. let params: [String:Any] = ["app_name": configuration.appName.rawValue,
  72. "app_version": version]
  73. unowned let weakSelf = self
  74. KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: params) { task, responseObject, error in
  75. if (error == nil && responseObject != nil) {
  76. let array = responseObject?["list"] ?? []
  77. //保存数据
  78. KMAdvertisementCache.default.saveData(data: array as! [NSDictionary])
  79. //解析数据
  80. weakSelf.parseData(data: array as! [NSDictionary]) { data in
  81. completion(data, nil)
  82. }
  83. } else {
  84. //获取缓存数据
  85. let cacheData = KMAdvertisementCache.default.readData()
  86. if cacheData.count != 0 {
  87. weakSelf.parseData(data: cacheData) { data in
  88. completion(data, nil)
  89. }
  90. } else {
  91. completion(nil, error!)
  92. }
  93. }
  94. }
  95. }
  96. }
  97. extension KMAdvertisementManager {
  98. //MARK: show
  99. /**
  100. @abstract 显示视图
  101. @param type 显示类型 <KMAdvertisementShowType>
  102. @param data 显示数据 <KMAdvertisementModel>
  103. @param superView 父视图 <NSView>
  104. @return KMAdvertisementModel
  105. */
  106. public func show(type: KMAdvertisementShowType?, data: KMAdvertisementModel?, superView: NSView?, _ action: KMAdvertisementActionCompletion?) -> NSView {
  107. var view = KMAdvertisementBaseView()
  108. #if os(OSX)
  109. if data != nil {
  110. if type == .list {
  111. view = KMAdvertisementTableView.init(data: data!, superView: superView!)
  112. } else if type == .view {
  113. view = KMAdvertisementShowView.init(data: data!, superView: superView!)
  114. }
  115. }
  116. #else
  117. if data != nil {
  118. if type == .scroll {
  119. view = KMAdvertisementShowScroll_iOS.init(data: data!, superView: superView!)
  120. } else if type == .view {
  121. view = KMAdvertisementShowView_iOS.init(data: data!, superView: superView!)
  122. }
  123. }
  124. #endif
  125. if action == nil {
  126. view.actionCompletion = { content in
  127. self.transitionAction(item: content)
  128. }
  129. } else {
  130. view.actionCompletion = action
  131. }
  132. return view
  133. }
  134. func transitionAction(item: KMAdvertisementModel.Section.Content) {
  135. if (item.actionType == .URL) {
  136. let string = item.linkURL?.en ?? ""
  137. #if os(iOS)
  138. if UIApplication.shared.canOpenURL(URL(string: string )!) {
  139. UIApplication.shared.open(URL(string: string )!, options: [:])
  140. }
  141. #elseif os(OSX)
  142. if NSWorkspace.shared.open(URL.init(string: string)!) {
  143. NSWorkspace.shared.open(URL.init(string: string)!)
  144. }
  145. #endif
  146. print("链接" + string)
  147. } else if (item.actionType == .comparative) {
  148. print("比较表")
  149. }
  150. }
  151. }
  152. extension KMAdvertisementManager {
  153. //MARK: data
  154. /**
  155. @abstract 解析数据
  156. @param data 传入参数 NSDictionary
  157. @return KMAdvertisementModel
  158. */
  159. public func parseData(data: [NSDictionary], completion:(_ result: [KMAdvertisementModel]) -> Void) -> Void {
  160. if (data.count != 0) {
  161. KMAdvertisementCache.default.saveData(data: data)
  162. }
  163. for model in data {
  164. var resultArray:[KMAdvertisementModel] = []
  165. if (self.allowLoadData(data: model)) {
  166. let jsonString: String = (model["detail"] as? String) ?? ""
  167. let jsonData: Data = jsonString.data(using: .utf8)!
  168. let decoder = JSONDecoder()
  169. // decoder.dataDecodingStrategy = .base64
  170. // decoder.keyDecodingStrategy = .convertFromSnakeCase //带下划线命名
  171. decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "+∞", negativeInfinity: "-∞", nan: "NaN")
  172. #if DEBUG
  173. //MARK: 测试使用
  174. let advertisementModel = try! decoder.decode(KMAdvertisementModel.self, from: jsonData)
  175. if (self.allowLoadContentData(data: advertisementModel)) {
  176. resultArray.append(advertisementModel)
  177. }
  178. #else
  179. // MARK: 此处try 使用 ? ,如果数据出问题 advertisementModel将无参数, 测试时使用!
  180. let advertisementModel = try? decoder.decode(KMAdvertisementModel.self, from: jsonData)
  181. if (advertisementModel != nil) {
  182. if (self.allowLoadContentData(data: advertisementModel)) {
  183. resultArray.append(advertisementModel!)
  184. }
  185. }
  186. #endif
  187. }
  188. completion(resultArray)
  189. }
  190. }
  191. func allowLoadData(data: NSDictionary) -> Bool {
  192. var result = false
  193. let status = (data["status"] as? Int) ?? 0
  194. let app_name: String = data["app_name"] as? String ?? ""
  195. if (status == 1 &&
  196. app_name == configuration.appName.rawValue) {
  197. result = true
  198. }
  199. return result
  200. }
  201. func allowLoadContentData(data: KMAdvertisementModel) -> Bool {
  202. var result = false
  203. let time: NSInteger = NSInteger(KMAdvertisementTimeStampConversion.getCurrentTimeInterval())!
  204. let startTime: NSInteger = NSInteger(data.startTime!)!
  205. let endTime: NSInteger = NSInteger(data.endTime!)!
  206. let platform = configuration.platform
  207. let subscribeType = configuration.subscribeType
  208. let version = data.version ?? "1.0"
  209. let localVersion = self.getLocalVersion()
  210. if (time >= startTime &&
  211. time <= endTime &&
  212. platform == data.platform &&
  213. self.compareVersion(nowVersion:localVersion, newVersion: version) &&
  214. subscribeType == data.subscribeType) {
  215. result = true
  216. }
  217. return result
  218. }
  219. //获取本地版本号
  220. func getLocalVersion() -> String {
  221. var localVersion = ""
  222. if let v: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
  223. localVersion = v
  224. }
  225. return localVersion
  226. }
  227. func compareVersion(nowVersion: String, newVersion: String) -> Bool {
  228. let nowArray = nowVersion.split(separator: ".")
  229. let newArray = newVersion.split(separator: ".")
  230. let big = nowArray.count > newArray.count ? newArray.count : nowArray.count
  231. for index in 0...big - 1 {
  232. let first = nowArray[index]
  233. let second = newArray[index]
  234. if Int(first)! <= Int(second)! {
  235. return true
  236. }
  237. }
  238. return false
  239. }
  240. }
  241. extension KMAdvertisementManager {
  242. // //MARK: image
  243. // public func dynamic_sdkBundle_image()-> NSImage? {
  244. // // class: 库里 任意class, dynamic bundle 和 mainBundle 不是同一个
  245. // let bundle = Bundle(for: KMAdvertisementManager.self)
  246. //// let mainBundle = Bundle.main
  247. // let path = bundle.path(forResource: "KMAdvertisement", ofType: "bundle")
  248. // if let path = path {
  249. // let sdkBundle = Bundle(path: path)
  250. // let filePath = sdkBundle?.pathForImageResource("1")
  251. // let image = NSImage.init(contentsOfFile: filePath!)
  252. //// let image = NSImage(named: "1", in: sdkBundle, compatibleWith: nil)
  253. // return image
  254. // }
  255. // return nil
  256. // }
  257. //
  258. // public func staticSdk_image() -> NSImage? {
  259. // // class: 库里 任意class
  260. // let bundle = Bundle(for: KMAdvertisementManager.self)
  261. // let path = bundle.path(forResource: "KMAdvertisement", ofType: "framework")
  262. // if let path = path {
  263. // let sdkBundle = Bundle(path: path)
  264. // let filePath = sdkBundle?.pathForImageResource("1")
  265. // let image = NSImage.init(contentsOfFile: filePath!)
  266. // return image
  267. // }
  268. // return nil
  269. // }
  270. }