PQThirdPlatformUtil.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. //
  2. // PQThirdPlatformUtil.swift
  3. // PQSpeed
  4. //
  5. // Created by SanW on 2020/5/30.
  6. // Copyright © 2020 BytesFlow. All rights reserved.
  7. //
  8. import Kingfisher
  9. import UIKit
  10. import UserNotifications
  11. import WechatOpenSDK
  12. import Bugly
  13. // MARK: - 第三方相关工具类
  14. /// 第三方相关工具类
  15. class PQThirdPlatformUtil: NSObject {
  16. static let shared = PQThirdPlatformUtil()
  17. // 注册第三方
  18. func register() {
  19. }
  20. override private init() {
  21. super.init()
  22. }
  23. override func copy() -> Any {
  24. return self
  25. }
  26. override func mutableCopy() -> Any {
  27. return self
  28. }
  29. }
  30. // MARK: - bugly相关工具类
  31. public class PQSingleBuglyUtil: NSObject {
  32. static let shared = PQSingleBuglyUtil()
  33. // 注册
  34. func register(appID:String) {
  35. // 注册bugly
  36. let buglyConfig = BuglyConfig()
  37. buglyConfig.reportLogLevel = .warn
  38. buglyConfig.version = versionName + "-\(PQENVUtil.shared.envMode)"
  39. BFLog(message: "Bugly版本号:\(BuglyConfig.version())")
  40. buglyConfig.channel = channelID
  41. buglyConfig.deviceIdentifier = BFLoginUserInfo.shared.isLogin() ? BFLoginUserInfo.shared.uid : getMachineCode()
  42. buglyConfig.unexpectedTerminatingDetectionEnable = true
  43. buglyConfig.blockMonitorEnable = true
  44. buglyConfig.blockMonitorTimeout = 2
  45. Bugly.start(withAppId: cBuglyAppkey, config: buglyConfig)
  46. }
  47. override private init() {
  48. super.init()
  49. }
  50. public override func copy() -> Any {
  51. return self
  52. }
  53. public override func mutableCopy() -> Any {
  54. return self
  55. }
  56. }
  57. // MARK: - 微信相关工具类
  58. /// 微信相关工具类
  59. //初始化微信要使用的参数 e.g.
  60. /*
  61. let state: String = "com.piaoquan.pqspeed"
  62. let appid: String = "wxfc2fc07ab379e4bf"
  63. let secret: String = "06f696424accb17b7234dce32e4821b4"
  64. let universalLink: String = "https://speed.piaoquantv.com/"
  65. let scope = "snsapi_userinfo"
  66. */
  67. public class WXApiInfo:NSObject {
  68. public var state: String = ""
  69. public var appid: String = ""
  70. public var secret: String = ""
  71. public var universalLink: String = ""
  72. public var scope = ""
  73. }
  74. public class PQSingletoWXApiUtil: NSObject {
  75. public static let shared = PQSingletoWXApiUtil()
  76. var openId: String? // openID
  77. // 回调
  78. public var wxApiUtilHander: ((_ userData: [String: Any]?, _ errorMsg: String?) -> Void)?
  79. var mAppInfo:WXApiInfo = WXApiInfo.init()
  80. public func registerApp(appInfo:WXApiInfo) {
  81. mAppInfo = appInfo
  82. #if DEBUG
  83. WXApi.startLog(by: .detail) { msg in
  84. BFLog(message: "微信回调Log--\(msg)")
  85. }
  86. #endif
  87. WXApi.registerApp(mAppInfo.appid, universalLink: mAppInfo.universalLink)
  88. // #if DEBUG
  89. // WXApi.checkUniversalLinkReady { step, result in
  90. // BFLog(message: "微信回调自检--\(step),result = \(result)")
  91. // }
  92. // #endif
  93. }
  94. public func handleOpen(url: URL) -> Bool {
  95. return WXApi.handleOpen(url, delegate: self)
  96. }
  97. public func handleOpenUniversalLink(userActivity: NSUserActivity) -> Bool {
  98. return WXApi.handleOpenUniversalLink(userActivity, delegate: self)
  99. }
  100. public func authorize() -> PQSingletoWXApiUtil {
  101. if !isInstallWX() {
  102. if wxApiUtilHander != nil {
  103. wxApiUtilHander!(nil, "您还未安装微信客户端!")
  104. }
  105. return .shared
  106. }
  107. let req = SendAuthReq()
  108. req.scope = mAppInfo.scope
  109. req.state = mAppInfo.state
  110. WXApi.send(req) { [weak self] isSuccess in
  111. if !isSuccess {
  112. self?.wxApiUtilHander!(nil, "您还未安装微信客户端!")
  113. }
  114. }
  115. return .shared
  116. }
  117. /// 分享
  118. /// - Parameters:
  119. /// - type: 类型 1- 分享视频 2-分享活动 3-分享卡点视频
  120. /// - scene: 场景
  121. /// - title: 标题
  122. /// - description:描述
  123. /// - imageUrl: 图片url
  124. /// - path: 网页地址
  125. /// - videoId: 视频ID type == 1时不为空
  126. /// - pageSource: 页面pageSource type == 1时不为空
  127. /// - Returns: <#description#>
  128. public func share(type: Int = 1, scene: Int32, shareWeappRawId: String? = nil, title: String?, description: String?, imageUrl: String?, path: String?, videoId: String, pageSource: PAGESOURCE, shareId: String) -> PQSingletoWXApiUtil {
  129. if !isInstallWX() {
  130. if wxApiUtilHander != nil {
  131. wxApiUtilHander!(nil, "您还未安装微信客户端!")
  132. }
  133. return .shared
  134. }
  135. let message = WXMediaMessage()
  136. message.title = title ?? ""
  137. message.description = description ?? ""
  138. ImageDownloader.default.downloadImage(with: URL(string: imageUrl ?? "")!, retrieveImageTask: nil, options: nil, progressBlock: nil) { image, _, _, _ in
  139. message.thumbData = zipImage(image: image, size: 64)
  140. if type == 1 || type == 3, scene == Int32(WXSceneSession.rawValue) {
  141. let wxMiniObject = WXMiniProgramObject()
  142. wxMiniObject.miniProgramType = PQENVUtil.shared.envMode == .ENVModeOnline ? .release : .test
  143. wxMiniObject.userName = shareWeappRawId ?? cShareWeappRawId
  144. var preParams: String = ""
  145. var page: String = ""
  146. var isRhythmVideo = 0
  147. if type == 3 {
  148. preParams = "package-point/show/show"
  149. page = "pages/post/post"
  150. isRhythmVideo = 1
  151. } else {
  152. preParams = "user-videos"
  153. page = "pages/category"
  154. isRhythmVideo = 0
  155. }
  156. var params = (preParams + "?id=\(videoId)&tp=share&rootPageSource=\(pageSource.rawValue)&shareDepth=1&rootLaunchShareId=\(shareId)&parentShareId=\(shareId)&shareId=\(shareId)&shareAppType=13&mid=\(getMachineCode())&su=\(BFLoginUserInfo.shared.uid)&isRhythmVideo=\(isRhythmVideo)").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
  157. ["/", "=", "?", "&"].forEach { char in
  158. let custom = CharacterSet(charactersIn: char).inverted
  159. params = params?.addingPercentEncoding(withAllowedCharacters: custom) ?? ""
  160. }
  161. wxMiniObject.path = "\(page)?jumpPage=" + (params ?? "")
  162. wxMiniObject.webpageUrl = "https://piaoquan.yishihui.com/"
  163. wxMiniObject.hdImageData = message.thumbData
  164. message.mediaObject = wxMiniObject
  165. } else {
  166. let webpageObject = WXWebpageObject()
  167. webpageObject.webpageUrl = path ?? ""
  168. message.mediaObject = webpageObject
  169. }
  170. let req = SendMessageToWXReq()
  171. req.message = message
  172. req.scene = scene
  173. WXApi.send(req) { [weak self] isSuccess in
  174. if self?.wxApiUtilHander != nil {
  175. self?.wxApiUtilHander!(nil, isSuccess ? "分享成功~" : "分享失败了~")
  176. }
  177. }
  178. }
  179. return .shared
  180. }
  181. /// 处理发起数据
  182. /// - Parameter response: <#response description#>
  183. /// - Returns: <#description#>
  184. public func dealWithPayParams(response: [String: Any]) -> PQSingletoWXApiUtil {
  185. var partnerid: String = ""
  186. var prepayId: String = ""
  187. var nonceStr: String = ""
  188. var timeStamp: UInt32 = 0
  189. var package: String = "Sign=WXPay"
  190. var sign: String = ""
  191. if response.keys.contains("partnerid") {
  192. partnerid = response["partnerid"] as! String
  193. }
  194. if response.keys.contains("prepayid") {
  195. prepayId = response["prepayid"] as! String
  196. }
  197. if response.keys.contains("noncestr") {
  198. nonceStr = response["noncestr"] as! String
  199. }
  200. if response.keys.contains("timestamp") {
  201. timeStamp = UInt32(Int("\(response["timestamp"] ?? "0")") ?? 0)
  202. }
  203. if response.keys.contains("package") {
  204. package = response["package"] as! String
  205. }
  206. if response.keys.contains("sign") {
  207. sign = response["sign"] as! String
  208. }
  209. requestPayReq(partnerid: partnerid, prepayId: prepayId, nonceStr: nonceStr, timeStamp: timeStamp, package: package, sign: sign)
  210. return .shared
  211. }
  212. /// 发起
  213. /// - Parameters:
  214. /// - partnerid: 商家向财付通申请的商家id
  215. /// - prepayId: 预
  216. /// - nonceStr: 随机串,防重发
  217. /// - timeStamp: 时间戳,防重发
  218. /// - package: 商家根据财付通文档填写的数据和签名
  219. /// - sign: 商家根据微信开放平台文档对数据做的签名
  220. /// - Returns: <#description#>
  221. public func requestPayReq(partnerid: String, prepayId: String, nonceStr: String, timeStamp: UInt32, package: String, sign: String) {
  222. // 调起微信
  223. let payReq: PayReq = PayReq()
  224. payReq.partnerId = partnerid
  225. payReq.prepayId = prepayId
  226. payReq.nonceStr = nonceStr
  227. payReq.timeStamp = timeStamp
  228. payReq.package = package
  229. payReq.sign = sign
  230. WXApi.send(payReq) { _ in
  231. }
  232. }
  233. /// 是否安装了微信
  234. /// - Returns: <#description#>
  235. public func isInstallWX() -> Bool {
  236. return UIApplication.shared.canOpenURL(URL(string: "weixin://")!)
  237. }
  238. override private init() {
  239. super.init()
  240. }
  241. public override func copy() -> Any {
  242. return self
  243. }
  244. public override func mutableCopy() -> Any {
  245. return self
  246. }
  247. }
  248. extension PQSingletoWXApiUtil: WXApiDelegate {
  249. public func onReq(_ req: BaseReq) {
  250. BFLog(message: "微信回调拉起 -- \(req)")
  251. if req.isKind(of: LaunchFromWXReq.self) && ((req as! LaunchFromWXReq).message.messageExt?.count ?? 0) > 0 {
  252. BFLog(message: "小程序回调数据--\(String(describing: (req as! LaunchFromWXReq).message.messageExt))")
  253. // PQBoardCommandUtil.dealWithPasteboardData(messageExt: (req as! LaunchFromWXReq).message.messageExt)
  254. }
  255. }
  256. public func onResp(_ resp: BaseResp) {
  257. BFLog(message: "微信回调返回 -- \(resp)")
  258. if resp.isKind(of: SendAuthResp.self) {
  259. if (resp as! SendAuthResp).state == mAppInfo.state {
  260. accessToken(code: (resp as! SendAuthResp).code!)
  261. } else {
  262. if wxApiUtilHander != nil {
  263. wxApiUtilHander!(nil, "网络不可用")
  264. }
  265. }
  266. } else if resp.isKind(of: PayResp.self) {
  267. if wxApiUtilHander != nil {
  268. wxApiUtilHander!(["returnKey": (resp as! PayResp).returnKey, "code": resp.errCode], resp.errStr)
  269. }
  270. }
  271. }
  272. public func accessToken(code: String) {
  273. let url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=\(mAppInfo.appid)&secret=\(mAppInfo.secret)&code=\(code)&grant_type=authorization_code"
  274. DispatchQueue.global(qos: .userInitiated).async { [weak self] in
  275. let zoneStr = try? String(contentsOf: URL(string: url)!, encoding: .utf8)
  276. if zoneStr == nil {
  277. if self?.wxApiUtilHander != nil {
  278. self?.wxApiUtilHander!(nil, "授权失败了~")
  279. }
  280. return
  281. }
  282. let data = zoneStr!.data(using: .utf8)
  283. let dict: [String: Any] = try! JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: Any]
  284. self?.openId = "\(dict["openid"] ?? "")"
  285. BFLoginUserInfo.shared.openId = self?.openId ?? ""
  286. let access_token: String = "\(dict["access_token"] ?? "")"
  287. let userUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=\(access_token)&openid=\(self?.openId ?? "")"
  288. DispatchQueue.global(qos: .userInitiated).async {
  289. let userInfoStr = try? String(contentsOf: URL(string: userUrl)!, encoding: .utf8)
  290. let userInfoData = userInfoStr!.data(using: .utf8)
  291. let userDict: [String: Any] = try! JSONSerialization.jsonObject(with: userInfoData!, options: .mutableContainers) as! [String: Any]
  292. DispatchQueue.main.async { [weak self] in
  293. if userDict.count > 0 {
  294. if self?.wxApiUtilHander != nil {
  295. self?.wxApiUtilHander!(userDict, nil)
  296. }
  297. } else {
  298. if self?.wxApiUtilHander != nil {
  299. self?.wxApiUtilHander!(nil, "授权失败了~")
  300. }
  301. }
  302. }
  303. }
  304. }
  305. }
  306. }