18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【iOS】続・半強制アップデートの仕組みをカジュアルに実装する

Last updated at Posted at 2021-10-12

はじめに

ユーザの端末にインストールされているアプリのバージョンが古いままだと、最新機能やバグ修正が提供できないだけでなく、メンテナンスが難しくなっていきます。ユーザには常に最新バージョンを使ってもらうのが望ましく、アップデートを促す仕組みは積極的に取り入れた方が良いと考えています。

アプリを起動したとき、最新バージョンがApp Storeにリリースされていることをユーザに伝え、アップデートを促す仕組みをこの記事では半強制アップデートと呼びます。

以前、「【iOS】半強制アップデートの仕組みをカジュアルに実装する」という記事でiTunes Search APIを利用した半強制アップデートの実装を紹介しました。このソースコードは僕が開発しているいくつものアプリに導入されており、これだけ流用するのならばフレームワーク化して一元管理した方が楽になってきます。
ということで、アプリの最新バージョンがApp Storeにリリースされたらアップデートを促す機能を提供するフレームワーク: SwiftyUpdateKitを作りました。なるべく少ないコード量で機能を実装できるように意識して作っています。

ソースコードはGitHubに公開しています。

SwiftyUpdateKitの使い方

インストール方法はSwiftPM、Carthage、CocoaPodsに対応しています。ビルド済のxcframeworkもReleasesにアップしてあります。詳しくはGitHubのREADMEを見てください。

初期化

AppDelegateクラスのapplication(_:,didFinishLaunchingWithOptions:)メソッド内でコンフィグを設定します。以下のコードのコメントを参考にしてください。

AppDelegate.swift
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メソッド内で実行します。

ViewController.swift
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以降が足されています。

ViewController.swift
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プロトコルと同様です。ユーザにレビューをお願いする条件をカスタマイズできます。

ViewController.swift
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())
    }
}

このコードは、

  1. 現在のアプリバージョンが最新でないならば、アップデートアラートを表示
  2. 最新Ver.にアプリがアップデートされた後、初めて起動された時にリリースノートを表示
  3. 最新Ver.のアプリであり、リリースノートも表示済みならば、レビューを要求

という挙動になります。

まとめ

SwiftyUpdateKitを使えば、簡単に以下の機能をアプリに組み込むことができます。

  • アプリの最新バージョンがApp Storeにリリースされたらアップデートを促す
  • アプリアップデート後の初回起動時に変更内容を伝えるリリースノートをユーザに表示
  • 任意の条件でユーザにレビューを要求

18
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?