zoukankan      html  css  js  c++  java
  • iOS使用Swift语言检查并提示更新

      项目要上线了,产品要求跟安卓一样,一进去有一个提示框提示更新。虽然苹果在 Settings/iTunes Store & App Store 选项中有自动更新这一选项,而且添加版本号等等有被拒绝的危险。但是..总之我建议大家要据理力争。不过既然需求下来了,我们应该怎么做呢?

      按照与之前的思路,我们是获取本地的版本号,以及从AppStore下载下来最新的版本号,两者进行比较,若本地版本号较低,则跳转至AppStore进行更新。首次使用Swift语言挑战,可能会有预知不到的错误,这样我们就分步做一下。

      1.获取本地版本号

      最简单。直接上代码。 

    1 // 取出本地版本号
    2 let localVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String    

      通过目录列表的信息字典,取出本地版本号。

      2.获取AppStore的版本号

      这个我们需要通过特定网址,请求AppStore的版本信息并解析出来。边上代码边分析:

      

        2.1 配置网络请求

    1 // AppStore地址(字符串)
    2 let path = NSString(format: "http://itunes.apple.com/cn/lookup?id=%@", appStoreId) as String
    3         
    4 // AppStore地址(URL)
    5 let url = NSURL(string: path)
    6         
    7 // 配置网络请求参数
    8 let request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 10.0)
    9 request.HTTPMethod = "POST"

        这里需要说明的一点是:cachePolicy的意思是缓存机制;其类型是个枚举,有以下几项:(自我感觉跑题了..)

     1 public enum NSURLRequestCachePolicy : UInt {
     2     
     3     case UseProtocolCachePolicy // 默认行为
     4     
     5     case ReloadIgnoringLocalCacheData //  不使用缓存
     6     case ReloadIgnoringLocalAndRemoteCacheData // Unimplemented (未实现) // 不使用任何缓存
     7     public static var ReloadIgnoringCacheData: NSURLRequestCachePolicy { get }
     8     
     9     case ReturnCacheDataElseLoad //  使用缓存(不管它是否过期),如果缓存中没有,那从网络加载吧
    10     case ReturnCacheDataDontLoad //  离线模式:使用缓存(不管它是否过期),但是从网络加载
    11     
    12     case ReloadRevalidatingCacheData // Unimplemented (未实现) // 在使用前去服务器验证 
    13 }

        我们选择的是 ReloadIgnoringLocalCacheData ,也就是不使用缓存;毕竟版本号是随时更新的。

        2.2 请求网络

     1 // 开始网络请求
     2         NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response, data, error) in
     3             
     4             // 声明获取的数据字典
     5             let receiveStatusDic = NSMutableDictionary()
     6             
     7             if data != nil {
     8                 
     9                 do {
    10                     // JSON解析data
    11                     let dic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
    12                     
    13                     // 取出版本号
    14                     // 判断是否resultCount为空
    15                     if let resultCount = dic["resultCount"] as? NSNumber {
    16                         
    17                         // 判断resultCount的数量是否大于0
    18                         if resultCount.integerValue > 0 {
    19                             
    20                             // 设置请求状态(1代表成功,0代表失败)
    21                             receiveStatusDic.setValue("1", forKey: "status")
    22                             
    23                             // 判断results是否为空
    24                             if let arr = dic["results"] as? NSArray {
    25                                 
    26                                 if let dict = arr.firstObject as? NSDictionary {
    27                                     
    28                                     // 取出version
    29                                     if let version = dict["version"] as? String {
    30                                         
    31                                         receiveStatusDic.setValue(version, forKey: "version")
    32                                         
    33                                         // 存网络版本号到UserDefaults里面
    34                                         NSUserDefaults.standardUserDefaults().setObject(version, forKey: "Version")
    35                                         
    36                                         NSUserDefaults.standardUserDefaults().synchronize()
    37                                     }
    38                                 }
    39                             }
    40                         }
    41                     }
    42                 }catch let error {
    43                     
    44                     print("checkUpdate -------- (error)")
    45                     
    46                     receiveStatusDic.setValue("0", forKey: "status")
    47                 }
    48             }else {
    49                 
    50                 receiveStatusDic.setValue("0", forKey: "status")
    51             }
    52             
    53             // 取出版本号后(若有则status为1,若没有则status为0),执行方法
    54             self.performSelectorOnMainThread(#selector(self.checkUpdateWithData(_:)), withObject: receiveStatusDic, waitUntilDone: false)
    55         }

        没有使用三方库诸如AFNetWorking或者SwiftHTTP来请求网络,主要是考虑三方库的版本差异;使用的系统的 NSURLConnection 进行网络请求,不过似乎过期了,应该使用NSURLSession;使用 NSJSONSerialization 来解析JSON数据。不要看步骤多,主要用来判断数据是否为空以及添加请求结果的状态了。同时将AppStore中的版本信息缓存到NSUserDefaults中,缓存一下。最后将请求后的数据与请求状态传递至处理数据的方法中即可。

      

      3.判断版本号

     1 // 判断版本号
     2     @objc private func checkUpdateWithData(data: NSDictionary) {
     3         
     4         // 判断请求网络版本号的状态
     5         let status = data["status"] as? String
     6         
     7         // 取出本地版本号
     8         let localVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
     9         
    10         if status == "1" {
    11             
    12             let storeVersion = data["version"] as! String
    13             
    14             self.compareVersion(localVersion, storeVersion: storeVersion)
    15             
    16             return
    17         }
    18        
    19         if let storeVersion = NSUserDefaults.standardUserDefaults().objectForKey("Version") as? String {
    20             
    21             self.compareVersion(localVersion, storeVersion: storeVersion)
    22         }
    23     }

      没啥好说的,对比两个版本号。若本地版本号较低,则执行下面的方法(跳转AppStore更新或者单纯的提醒一下用户该更新了)。

      

      4.更新

     1 private func compareVersion(localVersion: String, storeVersion: String) {
     2         
     3         if localVersion.compare(storeVersion) == NSComparisonResult.OrderedAscending {
     4             
     5             //做你想做的事情
     6             let alertController = UIAlertController.init(title: "更新可用", message: "(NSBundle.mainBundle().infoDictionary!["CFBundleDisplayName"])的新版本可用。请立即更新至(storeVersion)。", preferredStyle: UIAlertControllerStyle.Alert)
     7             
     8             let confirmAction = UIAlertAction.init(title: "更新", style: UIAlertActionStyle.Default, handler: { (alertAction) in
     9                 
    10                 
    11             })
    12             
    13             let nextTimeAction = UIAlertAction.init(title: "下一次", style: UIAlertActionStyle.Cancel, handler: nil)
    14             
    15             alertController.addAction(confirmAction)
    16             alertController.addAction(nextTimeAction)
    17             
    18             self.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
    19         }
    20     }

      我做的是跳转AppStore更新。就这样

  • 相关阅读:
    最接近原点的 K 个点
    水域大小
    根据数字二进制下 1 的数目排序
    有效的山脉数组
    岛屿的周长
    求根到叶子节点数字之和
    数组中的最长山脉
    [转] 结构体file_operations
    获取主机硬件资源 函数
    readdir() 获取文件类型
  • 原文地址:https://www.cnblogs.com/SoulKai/p/5924134.html
Copyright © 2011-2022 走看看