BLOGサブスレッドの日常

2017.03.29

iOS10 の UIWebView ではaタグによるカスタムURLスキームで他アプリ連携をしてくれなくなった

chao

はじめに

しみずです。どうぞよろしく。

WebViewを使うアプリを開発している時に、コンテンツ側にてaタグを利用して他アプリ連携を行うことがありました。
今までは機嫌よく動いてくれていたのですが、iOS10 あたり(確認したのは 10.2.1) から、それができなくなったようです。  

直し方

2通りの方法があります。
以下のいずれかを対応すれば良いです。

  1. UIWebViewのDelegateで、カスタムURLが呼ばれたら UIApplication#openURL() する
  2. info.plist の LSApplicationQueriesSchemes に起動したいスキームを追加する

きちんと直すなら後者の方が良いですが、どのスキームを呼ぶか分からない場合は前者でも良いと思います。
それぞれの対応方法についての詳細を書きます。

1. UIWebViewのDelegateで、カスタムURLが呼ばれたら UIApplication#openURL() する

UIWebView の delegate にある、webView:shouldStartLoadWithRequest:navigationType にて、ページ遷移前をフックし
カスタムURLスキームでの他アプリ呼び出しをネイティブ側で実行します。

http や file スキームの場合は、WebView側で処理させたいので true を返して WebView に任せます。(通常のページ遷移が行われる)
それ以外のスキームを UIApplication#openURL() で処理後、falseを返すことで WebView はページ遷移しません。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // httpまたはfileで始まるスキームは、WebView側で処理させる
    NSString *urlScheme = request.URL.scheme;
    if ([urlScheme hasPrefix:@"http"] || [urlScheme hasPrefix:@"file"]) {
        return true;
    }

    // カスタムURLスキームによる他アプリ起動(OSが知らないスキームだった場合は何もされない)
    [[UIApplication sharedApplication] openURL:request.URL];
    return false;
}

2. info.plist の LSApplicationQueriesSchemes に起動したいスキームを追加する

以下の手順にて info.plist に項目を追加します。

  1. info.pllist を開く
  2. LSApplicationQueriesSchemes という名前でArray型の項目を作成する
  3. 作成したArray型の項目の中に、起動したいアプリのスキーム名を記載する(hoge:// で起動するアプリの場合は hoge と記載する)

これを行うことで追加したスキーム名のスキームが aタグでも起動できるようになります。

また、UIApplication#canOpenURL() で起動できるURLかチェックする際に
info.plist に記載が無いと false が返ってくるようです。(iOS9からの挙動となります。)

起動するアプリが決まっているのであれば、こちらの方が正しい方法かと思います。

おわりに

記載した対策を行わなくても、写真起動(photos-redirect://) や、カレンダー起動(calshow:// )といった
始めからiOSにインストールされているアプリを起動するスキームの場合は、aタグでも起動できるようです。

この記事を書いた人

chao