新しいバージョンが利用可能になったことをユーザにお知らせする - Siren

# Siren とは？

アプリの新しいバージョンが利用可能になったことをユーザにお知らせアラートを表示するライブラリです。
本内容は Siren 5.2.1 をもとに記述しています。

<img width="200" alt="skip" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/df04bc78-9acb-aa8a-a64d-2c74d904063d.png">

* http://sabintsev.com/Siren

## シンプルな実装

import Siren 後、Siren.shared.wail() を didFinishLaunchingWithOptions で呼び出すだけで動作します。

```swift:AppDelegate.swift
import Siren // Line 1
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        window?.makeKeyAndVisible()
        Siren.shared.wail() // Line 2
        return true
    }
}
```

## カスタマイズ

Siren の Manager を設定することで次のようなカスタマイズが可能です。

* JP App Store でバージョンチェックしたい（デフォルトではUS）
* バージョン（メジャー、マイナー、パッチ、リビジョン）毎に細かく表示を分けたい
* アラートの表示頻度を変更したい（起動毎、日に１回、週に１回）
* ユーザの選択肢を制限したい（強制アップデート、次回更新、このバージョンをスキップ）

## JP App Store でバージョンチェックしたい

デフォルトでは US App Store に対してバージョンチェックを行います。
日本の App Store に対してバージョンチェックを行いたい場合は日本の App Store 向けに初期化したAPIManagerを用意します。

```swift
let siren = Siren.shared
siren.apiManager = APIManager.init(countryCode: "JP")
```

## バージョン（メジャー、マイナー、パッチ、リビジョン）毎に細かく表示を分けたい

RulesManaer を設定してアラートを表示するルールをカスタマイズ出来ます。
メジャー、マイナー、パッチ、リビジョンなど全ての更新に個別のルールを設定出来ます。

```swift
// 起動ごとにアラート表示、強制アップデートのルール
let forceRules = Rules.init(promptFrequency: .immediately, forAlertType: .force)

// 1日１回アラート表示、アップデートのタイミングはユーザが選べるルール
let optionRules = Rules.init(promptFrequency: .daily, forAlertType: .option)

// メジャーバージョンが上がった場合は強制アップデート
// マイナーバージョン以下のアップデートの場合はユーザに選択可能とする
let siren = Siren.shared
siren.rulesManager = RulesManager(
    majorUpdateRules: forceRules,
    minorUpdateRules: optionRules,
    patchUpdateRules: optionRules,
    revisionUpdateRules: optionRules,
    showAlertAfterCurrentVersionHasBeenReleasedForDays: 1)
)

```
## Rules

利用頻度が高そうなルールがあらかじめ用意されています。

| Rule | 説明 |
|:--|:--|
| annoying | アプリを起動するたびに表示<br>アプリの更新をスキップ可能 |
| critical | アプリを起動するたびに表示<br>アプリの更新を強制 |
| default | 日に１回表示<br>アプリの更新をスキップ可能<br>このバージョンをスキップも可能 |
| hinting | 週に１回表示<br>アプリの更新をスキップ可能 |
| persistent | 日に１回表示<br>アプリの更新をスキップ可能 |
| relaxed | 週に１回表示<br>アプリの更新をスキップ可能<br>このバージョンをスキップも可能 |

```swift
let siren = Siren.shared
siren.rulesManager = RulesManager(
    majorUpdateRules: .critical,
    minorUpdateRules: .default,
    patchUpdateRules: .default,
    revisionUpdateRules: .default,
    showAlertAfterCurrentVersionHasBeenReleasedForDays: 1)
)
```

## 独自 Rules

バージョンチェックの頻度やタイミング、ユーザへの選択肢を独自に設定することも可能です。
独自ルールで設定できる内容は下記の２つです。

### promptFrequency

ユーザにアプリ更新を促す頻度です。

| パラメタ | 説明 |
|:--|:--|
| immediately | アプリを起動するたびに表示 |
| daily | 日に１回表示 |
| weekly | 週に１回表示 |

### forAlertType

表示するアラートタイプです。ユーザが選べるボタンの数が変わります。

| パラメタ | 説明 | アラート |
|:--|:--|:--|
| force | ユーザにアプリの更新を強制する | <img width="200" alt="force" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/71dacc62-7583-a637-c020-3bfd89cceaff.png"> |
| option | 今すぐアプリを更新するか、起動時に更新する<br>どちらかユーザが選択できる | <img width="200" alt="option" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/b4ef2632-dff5-0082-bcc0-aeae27d79db4.png"> |
| skip | ・今すぐアプリを更新する<br>・次回の起動時に更新する<br>・このバージョンはスキップする<br>の内からいずれかをユーザが選択できる  | <img width="200" alt="skip" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/df04bc78-9acb-aa8a-a64d-2c74d904063d.png"> |

## releasedForDays

デフォルトでは更新アラートの表示を1日遅らせているそうです。
（showAlertAfterCurrentVersionHasBeenReleasedForDays: 1）
これは全ての地域の App Store CDN でバイナリが利用可能になる時間を待つためです。
通常、6〜24時間かかるため1日遅らせているようです。
showAlertAfterCurrentVersionHasBeenReleasedForDays に 0 を指定すると即時チェックとなりますがアラートが表示されるのに App Store にアップデートがまだ存在しない状況が発生する可能性があります。

## Localization

デフォルトではアプリの言語設定に従ってメッセージが表示されます。
設定が存在しない場合は英語で表示されます。
![SirenTest_xcodeproj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/9b2713dd-d9f1-67b9-21bb-2f08f3709ee5.png)
「設定 > 一般 > 言語と地域 > 使用言語」でメッセージが切り替わります。
<img width="300" alt="Simulator Screen Shot - iPhone Xs - 2019-09-20 at 15.25.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/e539f267-1da4-a291-981b-865030c4bdba.png"> <img width="300" alt="Simulator Screen Shot - iPhone Xs - 2019-09-20 at 15.22.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/5502e419-3937-2637-5222-abac16228a85.png">

### 言語を強制したい場合

例えばどんな場合でも日本語で表示したい場合は PresentationManager を指定します。

```swift
siren.presentationManager = PresentationManager(forceLanguageLocalization: .japanese)
```

### 独自の文言で表示したい場合

あらかじめ用意されたメッセージではなくオリジナルな文言を用いたい場合も PresentationManager を設定します。
ボタンの文字色も変更できます。

```swift
        siren.presentationManager = PresentationManager(
            alertTintColor: UIColor.orange,
            appName: "アプリ名",
            alertTitle: "新しいバージョンがあります",
            alertMessage: "新バージョンではXXX機能がご利用頂けます",
            updateButtonTitle: "アップデートする",
            nextTimeButtonTitle: "今はしない",
            skipButtonTitle: "次のバージョンまで表示しない",
            forceLanguageLocalization: .japanese)
```
<img width="375" alt="Simulator Screen Shot - iPhone Xs - 2019-09-20 at 15.50.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39953/8c44f9d0-c54e-1aae-8627-e29da8b7f7a1.png">

オリジナルのメッセージには新しいバージョン番号が表示されていますが、独自の文言を設定する場合には新しいバージョン番号を差し込むことは今のところできません。

## iOS13 対応

5.2.1 より古いバージョンでは、iOS13でダイアログが表示されてすぐ画面遷移してしまう不具合が発生していますので 5.2.1 以降へアップデートしましょう。