URLスキームで遷移した後にアプリに戻ってきた時の処理

URLスキームを使って別アプリに遷移した後で、アプリに戻ってきたタイミングで処理をするための手順メモ

今回は、アプリ内のPUSH設定画面から、URLスキームを使ってSettings.app内の当該アプリのPUSH設定画面へ遷移して、設定が完了したタイミングでユーザが「Back to XXXX（アプリ名）」で戻ってきたことを検知してアプリ側で必要な処理をする場合の手順ですが、Settings.app 以外の他のアプリへ遷移した場合も同様の手順でOKかと思います。

確認環境
* iOS:8.0〜
* Swift:2.2

# 1. URLスキームを使った画面遷移（今回は設定画面へ遷移）

<img width="371" alt="スクリーンショット 2016-05-29 18.57.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/26102/045c83fc-8b86-6b2e-22fb-d77731cca902.png">

アプリのSwitchをタップしたタイミングでSettings.app内の設定画面へ遷移。
実際にはSwitchタップのイベントの処理部分は[Eureka](https://github.com/xmartlabs/Eureka)を使って実装しているので細かいところは省略。

```
let url = NSURL(string:UIApplicationOpenSettingsURLString)!
UIApplication.sharedApplication().openURL(url)
````

<img width="370" alt="スクリーンショット_2016-05-29_19_10_30.png" src="https://qiita-image-store.s3.amazonaws.com/0/26102/394031eb-494c-355a-7958-27b0f4d13da4.png">


↓PUSH通知を許可

<img width="370" alt="スクリーンショット_2016-05-29_19_01_44.png" src="https://qiita-image-store.s3.amazonaws.com/0/26102/c912aba9-283f-30e1-26e9-72f7ab2df63a.png">

設定が完了したタイミングでユーザが「Back XXXX」で戻ってきたことをアプリ側で検知して処理をしたい。

# 2. 「Back to XXXX」で戻ってきたことをアプリ側で検知して処理

「Back to XXXX」を押下して、アプリに戻ってきたタイミングで、Settings.appでの設定内容をアプリ側にも反映する。

Settings.appでのPUSH設定内容をアプリ側で確認するためのコードはこんな感じ。

```
func isPushNotificationEnable() -> Bool {
    if UIApplication.sharedApplication().respondsToSelector(#selector(UIApplication.currentUserNotificationSettings)) == true {
        let settings = UIApplication.sharedApplication().currentUserNotificationSettings()
        if (settings?.types.contains(.Alert) == true){
            return true
        }
        else {
            return false
        }
    }
    return false
}
```

最初は、呼び出し元の画面で viewWillAppear が呼ばれるかな？思っていたのですが、viewWillAppear は呼ばれなかったので、別の手段で検知する必要があります。

# 3. applicationWillEnterForeground で検知

結論から言うと、Settings.app から元のアプリに戻ってきたタイミングで applicationWillEnterForeground が呼び出されていたので、こちらを検知して処理すればOKです。

呼び出し元のアプリで applicationWillEnterForeground を検知できるように NSNotificationCenter に登録
※ NotificationSettingsViewController の部分は自身で作成したViewで読み替えて下さい。

```
override func viewDidLoad() {
    ...
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NotificationSettingsViewController.applicationWillEnterForeground), name: UIApplicationWillEnterForegroundNotification, object: nil)
}
```  

検知した場合に実行するfunction

```
func applicationWillEnterForeground() {
    // isPushNotificationEnable()を呼び出してSettings.appでの設定内容をアプリ側に反映する
}
```

あとは viewDidDisappear のタイミングで一応 NSNotificationCenter での監視を停止。

```
override func viewDidDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}
```

こんな感じで、Settings.app からユーザが「Back to XXXX」で戻ってきたことを検知してアプリ側で必要な処理をすることが出来ました。

# 4. 蛇足

自分が実装しているアプリでは、PUSH通知が許可されていた場合には、PUSH通知する条件の一覧を表示しています。

<img width="372" alt="スクリーンショット 2016-05-29 18.57.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/26102/1cb5f18b-1c9c-7393-a124-765fd41cbefd.png">

PUSH通知にはFirebaseを使っているので、各キーワードのSwitchのON/OFFにあわせて、`FIRMessaging.messaging().subscribeToTopic(topic: String)`か`FIRMessaging.messaging().unsubscribeFromTopic(topic: String)`を呼び出してあげる感じ。

`subscribeToTopic()`や`unsubscribeFromTopic()`を連続で叩きまくるとエラーが返って来ていたので、そのあたりの詳しい話はまた別の機会に。