【Swift3】最新versionのインストールを促すアラートの表示


![IMG_0070.PNG](https://qiita-image-store.s3.amazonaws.com/0/24465/2c803a6c-795a-3975-19d2-54447f42ebc1.png "IMG_0070.PNG")

端末にインストールしているversionより新しいversionがリリースされていた場合にインストールを促すアラートを表示させるコードです。
以前、[Objective-Cで書いて](http://qiita.com/s0hno/items/b2596af8ddbf7c528cf9)Qiitaにあげたのですが、今回はSwift3で書き直しました。

##コード

```
import UIKit

/************変更箇所*************/

private let appId = ""
private let title = "アップデート"
private let message = "新しいVersionのインストール準備ができています。"
private let okBtnTitle = "今すぐインストール"
private let cancelBtnTitle = "後で"

/*******************************/

private var topViewController: UIViewController? {
    guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return nil }
    while let presentedViewController = topViewController.presentedViewController {
        topViewController = presentedViewController
    }
    return topViewController
}

enum UpdateType {
    case normal
    case force
}

class UpdateChecker {

    static func run(updateType: UpdateType) {
        guard let url = URL(string: "https://itunes.apple.com/jp/lookup?id=\(appId)") else { return }
        let request = URLRequest(url: url)
        let session = URLSession(configuration: .default)

        let task = session.dataTask(with: request, completionHandler: {
            (data, _, _) in
            guard let d = data else { return }
            do {
                guard let results = try JSONSerialization.jsonObject(with: d, options: .allowFragments) as? NSDictionary else { return }
                guard let resultsArray = results.value(forKey: "results") as? NSArray else { return }
                guard let storeVersion = (resultsArray[0] as? NSDictionary)?.value(forKey: "version") as? String else { return }
                guard let installVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return }
                guard installVersion.compare(storeVersion) == .orderedAscending else { return }
                showAlert(updateType: updateType)
            } catch {
                print("Serialization error")
            }
        })
        task.resume()
    }

    private static func showAlert(updateType: UpdateType) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: okBtnTitle, style: .default, handler: { Void in
            guard let url = URL(string: "itms-apps://itunes.apple.com/app/id\(appId)") else { return }
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        })
        alert.addAction(okAction)

        if updateType == .normal {
            let cancelAction = UIAlertAction(title: cancelBtnTitle, style: .cancel, handler: nil)
            alert.addAction(cancelAction)
        }

        topViewController?.present(alert, animated: true, completion: nil)
    }
}
```

##使い方

アラートを表示させたいタイミングで

```
UpdateChecker.run(updateType: .normal)
```

強制アップデートさせたい場合は以下のコードをapplicationDidBecomeActiveに書くと良いと思います。

```
UpdateChecker.run(updateType: .force)
```

コード上で下記のように括ってある部分は適宜変更してください。

```
/************変更箇所*************/
/*******************************/
```

##簡単に説明

下記URLを叩くとアプリの情報をjsonで取得できるので、

```
"https://itunes.apple.com/jp/lookup?id=\(appId)"
```
パースして、 端末にインストールしているアプリのversionと比較して、新しければshowAlertメソッドに飛ばすようにしています。

```
do {
    guard let results = try JSONSerialization.jsonObject(with: d, options: .allowFragments) as? NSDictionary else { return }
    guard let resultsArray = results.value(forKey: "results") as? NSArray else { return }
    guard let storeVersion = (resultsArray[0] as? NSDictionary)?.value(forKey: "version") as? String else { return }
    guard let installVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return }
    guard installVersion.compare(storeVersion) == .orderedAscending else { return }
    showAlert(updateType: updateType)
}
```

遷移ボタンをタップしたら、URLスキーム叩いてAppStoreに飛ばしています。

```
guard let url = URL(string: "itms-apps://itunes.apple.com/app/id\(appId)") else { return }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
```