// // CheckVersion.swift // WisdomCampusApk // // Created by 方楚豪 on 2022/1/20. // import UIKit import MMKV public func XWLog(_ message : T, file : String = #file, lineNumber : Int = #line) { #if DEBUG let fileName = (file as NSString).lastPathComponent print("[\(fileName):line:\(lineNumber)]- \(message)") #endif } public class AppCheckVersion: NSObject { /// 检查 app 是否需要去 AppStore 做版本更新 /// /// - Parameters: /// - appId: appId /// - completion: completion != nil时,显示自定义 view;completion == nil时,直接显示弹出框(显示API 请求内容) public class func checkVersion(_ appId: String, _ completion: ((_ dict: [String: Any]) -> ())?) { if completion == nil { requestAPI(appId) { (responseDict) in let message = responseDict["releaseNotes"] as? String ?? "" let alertContent = "\(message)\n\n是否前往 AppStore 更新版本?" let trackViewUrlString = responseDict["trackViewUrl"] as? String let hasIgnore:Bool = MMKV.default()!.bool(forKey: ConstantVC.HAS_IGNORE) if !hasIgnore { UIAlertController.alertTip(alertContent, trackViewUrlString) } } } else { requestAPI(appId, completion: completion) } } class func requestAPI(_ appId: String, completion: ((_ dict: [String: Any]) -> ())?) { let kItunesURL = "https://itunes.apple.com/cn/lookup?id=\(appId)" XWLog(kItunesURL) guard let url = URL(string: kItunesURL) else { XWLog("\(kItunesURL) is wrong.") return } var request:URLRequest = URLRequest.init(url: url) request.httpMethod = "POST" let dataTask = URLSession.shared.dataTask( with: request) {(responseData, response, error) in guard let data = responseData else { XWLog("response data is nil.") return } do { let dict = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as! [String: Any] XWLog(dict) guard let resultsArray = dict["results"] else { XWLog("results dictionary is nil.") return } let results = resultsArray as! [[String: Any]] if results.count > 0 { let responseDict = results.first ?? [:] let currentBundleShortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "" let lastVersion = responseDict["version"] as? String ?? "" /// to update if currentBundleShortVersion.compare(lastVersion) == .orderedAscending { // 忽略此版本后,如果APP又更新了一个版本,则不忽略 var appStoreVersion = "5.0.0" if MMKV.default()!.contains(key: ConstantVC.APP_STORE_VERSION) { appStoreVersion = MMKV.default()!.string(forKey: ConstantVC.APP_STORE_VERSION)! } if appStoreVersion != lastVersion { MMKV.default()?.set(false, forKey: ConstantVC.HAS_IGNORE) } MMKV.default()?.set(true, forKey: ConstantVC.HAS_NEW_VERSION) DispatchQueue.main.async { completion?(responseDict) } }else { MMKV.default()?.set(false, forKey: ConstantVC.HAS_NEW_VERSION) } MMKV.default()?.set(currentBundleShortVersion, forKey: ConstantVC.APP_VERSION) MMKV.default()?.set(lastVersion, forKey: ConstantVC.APP_STORE_VERSION) } } catch { XWLog(error) } } dataTask.resume() } } private var kContentLabKey = "" public extension UIAlertController { var contentLab: UILabel? { get { return objc_getAssociatedObject(self, &kContentLabKey) as? UILabel } set(newValue) { objc_setAssociatedObject(self, &kContentLabKey, newValue, .OBJC_ASSOCIATION_RETAIN) } } class func alertTip(_ contentString: String?, _ trackViewUrlString: String?) { guard let content = contentString, let trackViewUrlStr = trackViewUrlString, let appStoreURL = URL(string: trackViewUrlStr) else { return } let alertVC = UIAlertController(title: "更新", message: content, preferredStyle: .alert) let action = UIAlertAction(title: "前往", style: .default) { (action) in if UIApplication.shared.canOpenURL(appStoreURL) { if #available(iOS 10.0, *) { UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil) } else { // Fallback on earlier versions UIApplication.shared.openURL(appStoreURL) } } } alertVC.addAction(action) let action2 = UIAlertAction(title: "忽略此版本", style: .cancel) { (action) in MMKV.default()?.set(true, forKey: ConstantVC.HAS_IGNORE) } alertVC.addAction(action2) setContentLabAlignment(alertVC) let keyWindow = UIApplication.shared.connectedScenes .filter({$0.activationState == .foregroundActive}) .map({$0 as? UIWindowScene}) .compactMap({$0}) .first?.windows .filter({$0.isKeyWindow}).first keyWindow?.rootViewController?.present(alertVC, animated: true, completion: nil) } class func alertPayTip(_ contentString: String?, _ trackViewUrlString: String?) { guard let content = contentString, let trackViewUrlStr = trackViewUrlString, let appStoreURL = URL(string: trackViewUrlStr) else { return } let alertVC = UIAlertController(title: "提示", message: content, preferredStyle: .alert) let action = UIAlertAction(title: "前往", style: .default) { (action) in if UIApplication.shared.canOpenURL(appStoreURL) { if #available(iOS 10.0, *) { UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil) } else { // Fallback on earlier versions UIApplication.shared.openURL(appStoreURL) } } } alertVC.addAction(action) alertVC.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil)) setContentLabAlignment(alertVC) UIApplication.shared.keyWindow?.rootViewController?.present(alertVC, animated: true, completion: nil) } class func getLabs(_ view: UIView, _ alertVC: UIAlertController) { var isExist = false let subviews = view.subviews for v in subviews { if v.isKind(of: UILabel.self) { let lab = v as! UILabel if lab.text == (alertVC.message ?? "") { isExist = true alertVC.contentLab = lab break } } } if !isExist && subviews.count > 0 { getLabs(subviews.first ?? UIView(), alertVC) } } class func setContentLabAlignment(_ alertVC: UIAlertController) { getLabs(alertVC.view, alertVC) alertVC.contentLab?.textAlignment = .left } }