はじめに
こんにちは、suzukiです。iOSでアプリ間でデータのやり取りについてまとめました。今回の記事はURLスキームを主に説明いたします。
アプリ間連携とは
iOSではアプリ間で情報のやり取りをする方法がいくつかあります。
・URLスキーム
・App Groups
それぞれ簡単に特徴をまとめます。
URLスキーム
・異なるDeveloperアカウントから、リリースされたアプリで利用できる
・他のアプリからスキームを利用してアプリを起動することができる
・起動する際にURL形式で情報の受け渡しを行うことができる
・セキュアな情報のやり取りを行うと、脆弱性となりうる
App Groups
・同じDeveloperアカウントから、リリースされたアプリ間で利用できる
・他のアプリとUserDefault・KeyChain等を利用して、グループ内データの参照や編集ができる
・アプリの起動はできない
URLスキームの実装方法について
URLスキームの設定方法を具体的に説明すると、例えばSafariでtel://XXX-XXXX-XXXX(電話番号)と検索窓に入力すると電話アプリが呼び出されます。
電話アプリには”tel”というスキームが設定されているため、そのスキームが呼び出された際に起動が行われます。
上記の例では電話アプリでしたが、自作するアプリに任意のスキームを設定し、スキームを外部からの呼び出しを行うことができます。
URLスキームの設定
URLスキームに設定できる文字列には制限があります。Androidと微妙にルールが違うので、注意が必要です。
具体的にはハイフン、ドット、プラス以外の記号が使えない点に注意してください。
Androidはアンダースコアが設定できたりと動作が少し違います。
RFCに準拠したルールらしいです。
それでは実際に設定してみましょう。
TargetのInfoを選択すると下の方にURL Typesという項目があるので+ボタンを押します。
・identifierには適当な値(内部で参照されるだけなので重要ではない)
・urlSchemesには他のアプリからの呼出に使われる値
上記を入力しましょう。
ここまで完了したら実際にSafariの検索窓に”設定したスキーム://”と入力してください。
アプリの起動が確認できるはずです。
カスタムURLスキームの設定
さてURLスキームで呼び出すことに成功しましたが、その際に情報の受け渡しを行うことが可能です。
・アプリの特定の画面を呼び出したい
・他のアプリから、なんらかの値を渡したい
などを行いたい時は下記のようにURLスキームで呼び出された際のコードを記述しましょう。
SceneDelegate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { //URLとして受信 guard let url = URLContexts.first?.url else{ return } print("url:\(url)") guard let components = URLComponents(string: url.absoluteString) else { return } print("components:\(components)") //hostの取得 if let host = components.host{ print("host:\(host)") } //queryの取得 if let queryItems = components.queryItems { print("queryItems:\(queryItems)") } } |
基本的にはHostによって処理・画面を分岐させて、必要な情報はqueryとして受け取るという設計がいいみたいです。
ちなみにSafariでtest.scheme://category?id=7と入力した場合
1 2 3 4 | url:test.scheme://category?id=7 components:test.scheme://category?id=7 host:category queryItems:[id=7] |
こんな感じのログが出力されます。
URLスキームのセキュリティについて
URLスキームは便利なのですが、セキュリティの点でいくつか問題があります。
BundleIDのように一意な値ではないため、今回のtest.schemeを指定しても、必ず今回のアプリが開かれる保証がございません。
iOS11以降は同じスキームがある場合は先にインストールしたアプリが開かれます。
そのため、スキームが呼ばれた際に、どのアプリが起動されるかという保証がないためのっとりが行われたり等がございます。過去の事例として実際に問題になったこともあります。
URLスキームを利用し、セキュアな情報を連携することはやめた方が良さそうです。
最後に
最後までありがとうございます。異なるDeveloperアカウントからの連携を行う場合の方法を調べており、改めて機能としてまとめました。サーバーを介さないでセキュアな情報のやり取りは基本的にはできないという想定ですが、何かいい方法があるか調査中です。主にApp Extension周りは機能の追加が多いため、できることの確認から始めて行きます。