Custom URL Schemeでアプリ内の任意のページを表示する

Custom URL Scheme からアプリ起動する記事は多くあるのですが、アプリ起動した際に任意のページに遷移させるため日本語記事は思いの外少なかったので、自分が忘れないためにも書いていきます。

# 環境
- Xcode 8.2.1
- iOS 10.2.1
- デバイス iPhone6s

# やること
- URLからアプリ起動した際に任意のViewControllerへ遷移させる

# 手順
- Custom URL Scheme を設定する
- 遷移させたいViewControllerをインスタンス化する
- AppDelegateファイルに、URLからアプリ起動した場合の処理を記述する
- SafariからURLを入力して実際にアプリ起動してみる

# Custom URL Schemeを設定
Custom URL Schemeの設定方法は下記の2通りがあります。

- info.plistから設定
- TARGET > infoから設定

## info.plistから設定
ナビゲーションエリアのプロジェクトファイル内に入っているinfo.plistをクリックして、 `URL identifer` と `URL Schemes` を追加し任意の値を設定します。また、Schemeも任意の文字列を指定します。(今回はmyappとします。)

![plist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143619/c831153a-2487-5c9d-521d-a2ef349875d7.png)




## TARGET > infoから設定
ナビゲーションエリアからプロジェクトファイルを選択し、 TARGET > info > URL Types から `Identifier` と `URL Schemes` を追加し、任意の値を設定します。Schemeも同じく任意の文字列を指定します。

![project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143619/9481919d-ba85-8745-04f2-f882bcb6ba8e.png)


**※メモ**

- Schemeは複数個設定可能
- info.plist と　TARGET > infoどちらかが設定されていればもう片方に設定内容が反映される
- ブラウザからURLリクエストすると、クエリが全て小文字変換される様子(詳細は未調査)
- Xcode側ではURLリクエストを受け取った際にSchemeの大文字小文字の表現は揃えなくても正常に動作した。(詳細未調査)

ここまでの設定をすれば、 `myapp://` をブラウザなどからリクエストすると、設定を行ったアプリが起動します。


# ViewControllerをインスタンス化
URLからアプリ起動した際の遷移先ViewControllerをインスタンス化します。

- XcodeのナビゲーションエリアからMain.Storyboardを選択し、遷移先ViewControllerをクリック

![ski3.png](https://qiita-image-store.s3.amazonaws.com/0/143619/33581099-4653-ab7e-5369-2b5a0d532715.png)


- ユーティリティエリアの中からIdentity Inspectorを選択し、 Identity > Story Board ID のテキストエリアにViewControllerの識別子を入力します(識別子名は任意ですがここではViewController名を設定します)。この時 `Use Story Board ID` のチェックボックスを忘れずにチェックしてください。




これでViewController のインスタンス化ができたので、 Identifier で遷移させる ViewController を指定することができるようになりました。

# AppDelegateファイルにURLでアプリ起動した際の処理を書く
AppDelegate内の open url メソッドで、URLからアプリを起動した時の処理を書いていきます。
この時に使うNSURLクラスには、URL内の値を取得するメソッドが用意されています。

例えば、 `myapp://hoge/huga?xxx=1` などのURLの場合、下記のメソッドでそれぞれの値を引数として取得できます。

`.scheme` -> myapp
`.host` -> hoge
`.path` -> huga
`.query` -> xxx=1

今回は `host` メソッドを使います。

URLからアプリ起動した際に `host` に　`next` と入っていた場合は、指定したViewControllerへ遷移させる、という処理にします。

この時、遷移先のViewController名は仮に `nextViewContoller.swift` とし、リクエストするURLは `myapp://next` とします。

```AppDelegate.swift
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
       //URLの確認なので無くてもOK
       print(url)
       print(url.scheme)
       print(url.host)
       print(url.path)
       print(url.query)

       //リクエストされたURLの中からhostの値を取得して変数に代入
       let urlHost : String = url.host as String!
       
       //遷移させたいViewControllerが格納されているStoryBoardファイルを指定
       let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

       //urlHostにnextが入っていた場合はmainstoryboard内のnextViewControllerのviewを表示する
       if(urlHost == "next"){
           let resultVC: nextViewController = mainStoryboard.instantiateViewController(withIdentifier: "nextViewController") as! nextViewController
           self.window?.rootViewController = resultVC
       }
       self.window?.makeKeyAndVisible()
       return true
   }

```

これでiPhone内のブラウザから `myapp://next` と入力することで、nextViewController のページヘ遷移させることができます。

# SafariからURLを入力してアプリ起動する
iPhone内のSafariから `myapp://next` と入力した時に指定したページが表示されるか確認をします。
Initial Viewには Labelで `ViewController` 、遷移先のViewControllerには `nextViewController` と記載しています。

![DeepLink2.gif](https://qiita-image-store.s3.amazonaws.com/0/143619/874b74eb-7826-8636-4f6a-1a5bb2106a91.gif)


アプリ起動時に nextViewController が表示させることができました。
ディープリンクで詰まっている人の助けになれれば嬉しいです。


# 参考
http://dev.classmethod.jp/smartphone/ios-custom-url-scheme/
http://blog.nbostech.com/2016/03/deeplinking-in-ios-using-swift/
http://swiftdeveloperblog.com/deep-linking-using-custom-url-scheme/