子育てしながらエンジニアしたい

現在 7 歳 女の子の子育て中エンジニアによる、技術系 + 日常系ブログ。

Web ページから iOS アプリを起動したい - Custom URL scheme

やりたいこと

Web ブラウジングをしていて、ボタンやリンクを押すとアプリが起動する機能があります。
それを iOS で実現したい!ということで、その方法を調べました。
なお、ただ起動するだけでなく、起動時の URL も取得したかったので、その方法も含みます。

実現する方法

調べた感じでは、2 つの方法があるようです。

後者の Universal Links は iOS 9 で導入された機能のようで、UX 的にはこちらのほうが良さそうです。
ただ試すのにいろいろ制約 (SSL 接続必須とか、独自ドメインとか) があったので、今回は Custom URL scheme をやってみることにしました。
事情により Swift/Objective-C の両方でやる必要があったので、両方のやり方を紹介します。

Custom URL scheme

Custom URL scheme とは

ディープリンクとは、アプリの特定の画面に遷移(遷移先のアプリ側で実装が必要です)させることのできるリンクのことです。 iOSでは、 cm-app:// のような、アプリ固有の Custom URL Scheme を実装することで、これを実現できます。

ディープリンク(Custom URL Scheme)でアプリを起動する より

ウェブのリンクは通常 http:// とか https:// とかで始まります。
これをアプリ固有の myapp:// とか hogehoge:// とか (これを Custom URL scheme と呼ぶらしい) にすることで、この scheme を持ったアプリがインストールされていれば起動されます。

注意点としては、以下のようなことがあげられます。

  • 同じ scheme を持っているアプリがあった場合、どちらが起動するかわからない
  • scheme がなかったらエラーになる

後者に関してはいろいろ対策を考えられている方もいらっしゃるようです。

今回はここまで踏み込まず、アプリの起動と、そのときの URL の取得までを行います。

アプリに Custom URL scheme を設定する

これは非常に簡単です。
プロジェクトの Info -> URL Types を開き、+ ボタンを押します。
すると下記のようになるので、ここの URL Schemes に使いたい scheme 名を入力します。

f:id:edosha:20170502162802p:plain

ここでは sctest としました。

リンクを作成する

これもとっても簡単です。
html に以下のように記述すれば OK です。

<a href="sctest://">Launch!!</a>

iOS 側でこのリンクをクリックすると、以下のような画面になります。

f:id:edosha:20170502163340p:plain

これだけで、アプリの起動までは完了です。

起動時の URL を取得する

ただ今回はこれだけではなく、起動時の URL をアプリ側で取得したかったのです。
それによってアプリの動作を変えるってことも簡単にできるので。
たとえば html ファイルのリンクを以下のようにして、ユーザ名やパスワード等をアプリに渡すことを考えます。

<a href="sctest://user:password@192.168.100.100:5555/#fragment">Launch!!</a>

Swift/Objective-C それぞれやり方が微妙に違ったので、どちらも紹介します。

Swift

AppDelegate.swift ファイル内に AppDelegate クラスがあります。
そのクラスのどこかに以下のような記述を入れます。

func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    print("scheme: \(url.scheme!)")
    print("user: \(url.user!)")
    print("password: \(url.password!)")
    print("host: \(url.host!)")
    print("port: \(url.port!)")
    print("fragment: \(url.fragment!)")
        
    return true
}

こうすると Xcode の出力部に以下のように出力されます。

f:id:edosha:20170502165800p:plain

なお url から取れる情報は、Apple の開発者ページが参考になります。
NSURL

実装は下記のページを参考にしました。
とても詳しく書いてあるのでおすすめです。
ディープリンク(Custom URL Scheme)でアプリを起動する

Objective-C

AppDelegate.m ファイルのどこかに以下のような記述を入れます。

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    NSLog(@"scheme: %@", url.scheme);
    NSLog(@"user: %@", url.user);
    NSLog(@"password: %@", url.password);
    NSLog(@"host: %@", url.host);
    NSLog(@"port: %@", url.port);
    NSLog(@"fragment: %@", url.fragment);
    
    return YES;
}

こうすると、ターミナルのログに以下のように出力されます。

f:id:edosha:20170502170242p:plain

Swift と同じですが、url から取れる情報は、Apple の開発者ページが参考になります。
NSURL

ログの確認は以下のページを参考にしました。
iOS Simulatorのシステムログを確認する

さいごに

思ったよりも簡単にできてしまいました。
いや〜、iOS アプリすごいですね...