[iOS]アプリに強制アップデート機能を導入すべき理由と、簡単に実装する方法

##強制アップデートとは？
多くのアプリを利用されている方でしたら、何度か下記の画像のようなアラートでアップデートを促されたことがあるかと思います。このアラートは閉じるボタンが存在せず、「AppStoreへ」のボタンしか存在しないため、ユーザーにはアプリを操作するためにはアプリをアップデートする以外に選択肢がありません。この記事では、この様なアラートをアプリ起動時に表示する機能を強制アップデート機能と呼び、なぜそれが必要なのかと、<b>たった3行でこの機能を導入できる</b>ライブラリについて記述します。

![](https://dl.dropboxusercontent.com/u/461628/SRGVersionUpdater_SampleView.jpg)


##なぜ強制アップデートが必要なのか？
iOS7以降、自動アップデート機能は追加されたもののもちろん全てのユーザーがそれを利用しているわけではありません。中には、リリースから半年以上経過しても初期バージョンを利用し続けるユーザーの方もいます。では、この様に古いバージョンを利用しているユーザーも多くいる状態で、例えば下記の様な問題が発生したケースを考えてみます。

* 古いバージョンのアプリで特定の操作を行うと、データが破損しアプリの操作が不可能となるバグが発見された
* サーバーサイドとの通信部分で使う認証ロジックに問題があり、古いバージョンでの認証ロジックのままでは成り済ましが出来てしまう脆弱性が発見された

これを読んでる方の中にはこの例を読んで、過去の思い出が頭をよぎり胃が痛くなるという人もいるかもしれません。どちらの例も、極めて深刻な状況ですが、実際起こりうるケースです。そしてどちらの例でも、古いバージョンのアプリを継続して利用してるユーザーがいるという状態でアプリを運用するということは、いつ爆発するかわからない爆弾を抱えたまま走り続けるのと同義です。迅速に、全てのユーザーを最新版へと移行させる必要があります。

ここで、問題のある古いバージョンに強制アップデート機能が実装されていなかった場合のことを考えてみて下さい。全てのユーザーを最新版に移行させることは、可能でしょうか？もしもアプリ内に、ユーザーに問題が発生していることを告知する機能や、アップデートを促す機能が無かった場合、恐らくそれは極めて難しいでしょう。強制アップデート機能が実装されれば最新版への移行をスムーズに行うことが出来ますが、強制アップデート機能を追加するためにはアップデートが必要であるという、デッドロックの状態です。

このように **既に配布済みのバージョンに強制アップデート機能が実装されていなかった場合、全てのユーザーを最新版に移行させることは極めて難しくなる** と思われます。このような理由から、新規アプリをリリースする際には **リリースバージョンからこの強制アップデート機能を導入しておくことをお勧めします。**

実際には上記の様なトラブルが起こることは稀ですが、問題が発生したときに古いバージョンを利用してるユーザーに、アプリをアップデートしてもらう方法が無くなってしまうというリスクを考えると、強制アップデートを保険として実装しておく、というのはアリだと思います。

##SRGVersionUpdater
SRGVersionUpdaterは、強制アップデート機能を3行のコードと、サーバーに配置するjsonファイルのみで簡単に実装できるライブラリです。後述しますが、jsonファイルをサーバーに配置する作業はDropboxかGoogleDriveのアカウントさえあれば誰でも簡単に行うことが出来るため、サーバーサイドのプログラミングの知識等は一切必要ありません。

https://github.com/kazu0620/SRGVersionUpdater

##導入手順
####1.JSONファイルを用意する
まず下記の内容のJSONファイルを用意します。下の一行をお好きなエディタにコピーして保存し名前をつけて保存して下さい。今回の説明ではapp_version.jsonという名前で保存しています。

```json
{"required_version":"2.0.0","type":"force","update_url":"https://itunes.apple.com/jp/app/idxxxxxxxxxx?mt="}
```


次に、3つの値を下記の内容に沿って変更して下さい。基本的には、required_versionを最新版のアプリバージョンに、update_urlを対象のアプリのApp Store URLに書き換えれば問題ありません。

| key | define |
|--------|--------|
|   required_version     |   必要とされるバージョンを入力します。ここで指定したバージョンに達していないアプリを利用してる全てのユーザーに、強制バージョンアップの告知が表示されます。      |
|     type   |    基本的には強制バージョンアップを行うことを前提に解説していますが、SRGVersionUpdaterではキャンセルボタン付きの告知アラートを表示することも出来ます。強制アップデートの場合は"force" を任意でのアップデートの場合は"optional"を入力して下さい。      |
|     update_url   |  アップデート対象となるアプリのApp SotreURLを入力します。     |

####2.JSONファイルをサーバーに配置する
もちろん、手元でいじれるサーバー環境があればそちらを利用したほうが良いのですが、JSONは静的なファイルなので小規模なアプリの場合ならGoogleDriveやDropboxの公開機能を使って手軽に配信することもできます。詳細については、下記にわかりやすい説明がありました。

[Dropboxを利用する場合](http://www.goarch.org/archdiocese/departments/internet/articles/dropbox/)
[GoogleDriveを利用する場合](https://sites.google.com/a/griffith.edu.au/staff-email-learning-centre/help-yourself/google-drive-docs/how-to-share-a-file-with-a-non-google-colleague)

ただ上記の様なサービスは本来はファイルをホスティングするためのサービスではないので帯域制限がある、安定性に欠ける、などの問題が等があります。個人で開発している小さなアプリならDropboxやGoogleDriveで試してみるのも問題ないですが、商用のプロジェクトやダウンロード数が大きいアプリの場合は、必ず専用のホスティングサービスやWEBサーバー等を利用してください。


####3.プロジェクトにSRGVersionUpdaterをインストールする
Podfileに以下の行を追加してpod updateすれば、SRGVersionUpdaterをインストールすることが出来ます。

``` ruby
pod 'SRGVersionUpdater', "0.0.2"
```

次に、application didFinishLaunchingWithOptions:の中に下記の処理を追記します。

objective-cの場合

```objc:objective-cの場合
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    SRGVersionUpdater *versionUpdater = [SRGVersionUpdater new];
    versionUpdater.endPointUrl = @"http://xxxxxxxxxxxxx/app_version.json";
    [versionUpdater executeVersionCheck];
    
    return YES;
}
```

swiftの場合

```objc:swiftの場合
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        let versionUpdater = SRGVersionUpdater()
        versionUpdater.endPointUrl = "http://xxxxxxxxxxxxx/app_version.json"
        versionUpdater.executeVersionCheck()
        
        return true
    }
```

    
最後に、endPointUrlの中身を先ほどアップロードしたJSONのURLに書き換えれば、完了です。指定したrequired_versionよりも低いバージョンのアプリを起動すれば、ポップアップが表示されることを確認できるはずです。

## 強制アップデートを行う時の注意点など
これまでの経験上、最新版のアプリを配信開始しiTunes Connectの状態がReady for Saleとなっていても実際にApp Storeに反映されるまでには1〜3時間程度の時間差がありました。また、端末によっても反映されるタイミングが多少違うようなので、Ready for Saleとなってから3〜5時間ほど時間をおいて、実機でバージョンアップが出来ることを確認してから、強制アップデートを実施するのが良いと思われます。