[Swift3]アプリ内でレビューを依頼する

# アプリ内レビューとは
アプリのダウンロード数を向上させる手段の一つとしてアプリへの良いレビューを多く書いてもらうという戦略があります。

その際に活用するのがアプリ内レビューです。

端的に言うとユーザーの特定のアクションをフックしてアプリ内レビュー依頼を行い、同意したユーザーに対してレビューを書いてもらうというもの。

このアプリレビュー依頼は訴求タイミングが良くなかったり、表現方法に工夫が無いとネガティブなレビューを書かれてしまう可能性もあるため、ただ単に実装すれば良いと言うものではないと言えます。

また、iOS10.3以降とそれ以外のOSバージョンとではレビュー依頼の挙動が異なるので、そのあたりについても書いていきたいと思います。

# できたもの
先に書いた様に、OSのバージョン依存でレビュー依頼時の挙動が変わるので、バージョン別に説明します。

因みに下記のソースは僕の[Github](https://github.com/takuyama29/InAppReview)でも公開しているのでぜひ使って下さい。

### iOS10.3未満
iOS10.3未満の場合は、アプリ内からAppStoreアプリのレビューページへ遷移させることでレビューを書いて貰います。

![iOS10.gif](https://qiita-image-store.s3.amazonaws.com/0/143619/84fe02a8-47f8-96db-7876-40a5c97ac01a.gif)

### iOS10.3以降
iOS10.3以降では新しく追加されたフレームワーク[StoreKit](https://developer.apple.com/documentation/storekit)を利用したレビュー依頼が推奨されており、このフレームワークを活用するとAppStoreへ遷移せずにレビューをして貰うことができます。

またこのフレームワークを活用すると、星いくつかという評価しかできないようになっています。

![iOS10.3.gif](https://qiita-image-store.s3.amazonaws.com/0/143619/51486742-b139-bf29-14de-65e3548609cb.gif)

※今回使用したプロジェクトは実際にリリースされているアプリではないので、評価後にレビューを `送信` するボタンがdisableになっています。

# 実装

下記の`id1274048262`の部分を、自分のリリースされているアプリのidに書き換えることで、AppStroe内のレビュー画面飛ばし先を変更することができます。

また、`?action=write-review`のパラメータは、AppStoreのアプリ詳細画面遷移後にレビューページをmodal表示する為のパラメータです。

通常、アプリのレビューをする場合は
1. AppStoreアプリを起動
2. レビュータブを選択
3. `レビューを書く`を押す

という手間が発生してしまいますが、このパラメータを付与することでその手間を省くことができるので、よりレビューを書くまでの工数が削減されて便利です。

上記については[【Swift】AppStoreのレビューフォームを開くパラメーターが新登場 - action=write-review -](http://qiita.com/mshrwtnb/items/8fd60ba3a8bc89f3c013)を参考にさせて貰いましたm(_ _)m

```ViewController.swift
import StoreKit

...

    @IBAction func requestReviewButton(_ sender: UIButton) {
        // レビューページへ遷移
        if #available(iOS 10.3, *) {
            SKStoreReviewController.requestReview()
        }
            // iOS 10.3未満の処理
        else {
            if let url = URL(string: "itms-apps://itunes.apple.com/app/id1274048262?action=write-review") {
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(url, options: [:])
                } else {
                    UIApplication.shared.openURL(url)
                }
            }
        }
    }

```

# 訴求タイミングと文言について
アプリのレビュー依頼は、ユーザーがアプリ内で何か目的を達成した際などに訴求すると良い。などと言われることがあります。

例えば
1. ゲームのチュートリアルをクリアした
2. ダイエット目標をクリアした
3. 1週間連続でアプリ起動した
4. 一定以上のいいねを獲得した
5. アプリ内決済が完了した

などがあるかと思いますが、上記の様なタイミングで訴求を行うことでユーザーにより**高い評価を付けて貰いやすくなる**可能性が高くなると個人的に思っています。

また、低い評価を書かれないようにする対策としては、アプリレビュー依頼時の文言などに工夫をすることで解決できるのではないかと考えています。

~~僕の場合は、レビュー画面へ遷移もしくは、レビューダイアログを表示する前に「もしよろしければレビューに★5を付けてくれませんか？」といった様なダイアログを表示し、そこで`OK`と回答してくれた人だけにレビュー依頼をするようにしています。~~

<img width="375" alt="Screen Shot 2017-09-05 at 17.01.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/143619/16181770-989f-2145-52b9-0eacbbb36d1e.png">

~~こうすることで、必然的に星５以外のレビューが書かれない様にしています。
この方法が正しいかどうかは現在検証中なので、参考程度に聞いていただければ幸いです。~~


**追記**
@iganin さんから指摘を貰い修正しました。
Appleが上記の様なレビューを促す行為を今後禁止することを[App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/)で示しています。

```
Use the provided API to prompt users to review your app; this functionality allows customers to provide an App Store rating and review without the inconvenience of leaving your app, and we will disallow custom review prompts.
```
そのため、アプリ内においてカスタムビューなどでレビューを促す処理をしている場合、今後はアプリの審査が通らない場合があるので注意して下さい。

また、 @mshrwtnb さんからもコメントでいただいた様に、`SKStoreReviewController.requestReview()`はリリースアプリにおいて確実に表示されることが保証されていないため、ボタンタップ時などユーザー操作が発生した際に表示するのは適切では無いようです。

[requestReview()](https://developer.apple.com/documentation/storekit/skstorereviewcontroller/2851536-requestreview)を参照

```
Because this method may or may not present an alert, it's not appropriate to call it in response to a button tap or other user action.
```