はじめに
ユーザの端末にインストールされているアプリのバージョンが古いままだと、最新機能やバグ修正が提供できないだけでなく、メンテナンスが難しくなっていきます。ユーザには常に最新バージョンを使ってもらうのが望ましく、アップデートを促す仕組みは積極的に取り入れた方が良いと考えています。
アプリを起動したとき、最新バージョンがApp Storeにリリースされていることをユーザに伝え、アップデートを促す仕組みをこの記事では半強制アップデートと呼びます。
以前、「【iOS】半強制アップデートの仕組みをカジュアルに実装する」という記事でiTunes Search APIを利用した半強制アップデートの実装を紹介しました。このソースコードは僕が開発しているいくつものアプリに導入されており、これだけ流用するのならばフレームワーク化して一元管理した方が楽になってきます。
ということで、アプリの最新バージョンがApp Storeにリリースされたらアップデートを促す機能を提供するフレームワーク: SwiftyUpdateKitを作りました。なるべく少ないコード量で機能を実装できるように意識して作っています。
ソースコードはGitHubに公開しています。
SwiftyUpdateKitの使い方
インストール方法はSwiftPM、Carthage、CocoaPodsに対応しています。ビルド済のxcframeworkもReleasesにアップしてあります。詳しくはGitHubのREADMEを見てください。
初期化
AppDelegateクラスのapplication(_:,didFinishLaunchingWithOptions:)
メソッド内でコンフィグを設定します。以下のコードのコメントを参考にしてください。
import SwiftyUpdateKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let config = SwiftyUpdateKitConfig(
// 現在のアプリバージョン
// 普通は以下の通りInfo.plistのバージョンを指定すれば良いはずです
version: Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String,
// iTunes ID
// iTunes IDはブラウザでApp Storeのアプリページを開いたときのURLから分かります
// e.g.) App Store URL: "https://apps.apple.com/app/sampleapp/id1234567890" -> iTunesID is 1234567890
iTunesID: "1491913803",
// App StoreのアプリページのURL
storeURL: "https://apps.apple.com/app/blue-sketch/id1491913803",
// iTunes Search APIで使う国コード。省略したときはUSの情報を取得します
// 国コードは↓で調べられます
// http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
// 多言語対応するときはこの国コードを切り替えてください
country: "jp",
// アプリバージョンの比較方法
// 省略したときはX.Y.Z形式のバージョンをstoreVersion > currentVersionかで比較します
versionCompare: VersionCompare(),
// アップデートアラートのタイトル
updateAlertTitle: "新しいバージョンがあります!",
// アップデートアラートのメッセージ
updateAlertMessage: "アプリをアップデートしてください。アップデート内容の詳細はApp Storeを参照してください。",
// アップデートアラートの更新ボタン
updateButtonTitle: "アップデート",
// アップデートアラートのキャンセルボタン
// nilを指定したときは非表示 -> キャンセル不可のためアップデートを強制します
remindMeLaterButtonTitle: "また後で"
)
// コンフィグをセットし初期化
// 第2引数のクロージャをセットしたときはフレームワークの内部ログを出力します
SUK.initialize(withConfig: config) { print($0) }
return true
}
}
iTunes IDの調べ方はこちらを参考にしてください。
バージョンチェックする
現在のアプリバージョンとApp Storeにリリースされているバージョンを比較するためにはcheckVersion
メソッドをviewDidAppear
メソッド内で実行します。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
SUK.checkVersion(VersionCheckConditionAlways())
}
この一行でバージョン比較を行ない、最新バージョンがApp Storeにリリースされていた場合は以下のようなアップデートアラートを表示します。アラートのテキストはコンフィグで設定したものになります。
checkVersion
メソッドの引数のVersionCheckCondition
には以下の種類があります。
// 常にバージョンチェックを行ないます
VersionCheckConditionAlways()
// 一日一回バージョンチェックを行ないます
// 1回チェックした後は日付が変わるまでチェックを行ないません
VersionCheckConditionDaily()
// 常にバージョンチェックを行ないません
VersionCheckConditionDisable()
この他に独自の条件を指定したい場合はVersionCheckCondition
プロトコルを実装し、そのオブジェクトを引数に指定してください。
public protocol VersionCheckCondition: AnyObject {
/// If returns true, checks the app version.
func shouldCheckVersion() -> Bool
}
以前の記事では半強制アップデートの仕組みまでを紹介していました。SwiftyUpdateKitには更に追加の機能を用意しています。
アップデート後にリリースノートを表示する
SwiftyUpdateKitを使えば、アプリアップデート後の初回起動時に変更内容を伝えるリリースノートをユーザに表示できます。以下のコードを御覧ください。先程のコードにnewRelease
以降が足されています。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
SUK.checkVersion(VersionCheckConditionAlways(), newRelease: { [weak self] newVersion, releaseNotes, firstUpdated in
guard let self = self else { return }
SUK.showReleaseNotes(from: self, text: releaseNotes, version: newVersion)
})
}
このコードはアプリのバージョンチェックを行ない最新Ver.であったとき、newRelease
クロージャが呼ばれます。その中でshowReleaseNotes
メソッドを実行すると以下のようなViewControllerが表示されます。text
に渡しているreleaseNotes
は、App StoreのリリースノートをiTunes Search APIで引っ張ってきたものになります。firstUpdated
フラグは、SwiftyUpdateKitを導入して初めてアップデートしたとき(初回インストール含む)のみtrue
になります。
showReleaseNotes
メソッドの代わりに任意のViewControllerやViewを作って表示しても構いません。(デフォルトのViewControllerはかなりシンプルなので)
アプリレビューを要求する
もう一つの追加機能は以下のようなアプリレビューを要求できます。
以下のコードは、先程のコードにrequestReview
メソッドが足されています。requestReview
メソッドの引数のRequestReviewCondition
は、VersionCheckCondition
プロトコルと同様です。ユーザにレビューをお願いする条件をカスタマイズできます。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
SUK.checkVersion(VersionCheckConditionAlways(), newRelease: { [weak self] newVersion, releaseNotes, firstUpdated in
guard let self = self else { return }
SUK.showReleaseNotes(from: self, text: releaseNotes, version: newVersion)
}) {
SUK.requestReview(RequestReviewConditionAlways())
}
}
このコードは、
- 現在のアプリバージョンが最新でないならば、アップデートアラートを表示
- 最新Ver.にアプリがアップデートされた後、初めて起動された時にリリースノートを表示
- 最新Ver.のアプリであり、リリースノートも表示済みならば、レビューを要求
という挙動になります。
まとめ
SwiftyUpdateKitを使えば、簡単に以下の機能をアプリに組み込むことができます。
- アプリの最新バージョンがApp Storeにリリースされたらアップデートを促す
- アプリアップデート後の初回起動時に変更内容を伝えるリリースノートをユーザに表示
- 任意の条件でユーザにレビューを要求