Share Extensionを実装してつまずいた話

Share Extensionを実装してつまずいた話 トラブルシューティング

Visionでバーコード・QRコードを読み取る機能を実装した後、以前Notification Service Extensionでリッチ通知を実装した経験を活かし、他のアプリから直接データを受け取れるShare Extensionに挑戦しました。

1. アプリ本体のコードがそのまま動くと思っていた

最初、新規ターゲットとしてShare Extensionを追加すれば、アプリ本体のViewControllerやデータ管理コードをそのまま呼び出せると思い込んでいました。

class ShareViewController: SLComposeServiceViewController {
}

しかし、Share Extensionはアプリのメインターゲットとはメモリもプロセスも分離された独立した実行環境であり、アプリ本体のインスタンスやシングルトンに直接アクセスすることはできないと分かりました。データをやり取りするには、App Groupsなど別の共有の仕組みを使う必要がありました。

2. どんな種類の共有データにも対応できると思っていた

共有シートにアプリのアイコンを表示させたものの、期待していたSafariのURL共有では表示されるのに、写真アプリの画像共有では表示されないことがありました。

不足していた設定:
NSExtensionActivationRule に対応データ型の条件指定

Info.plistのNSExtensionActivationRuleで、対応する共有データの種類(URL、画像、テキストなど)を明示的に指定する必要があることが分かりました。デフォルトの設定のままでは想定していたデータ型に対応しておらず、共有シートの候補にすら表示されない状態になっていました。

3. 受け取ったデータの取り出し方が分からず苦労した

対応データ型を設定した後、実際に共有されたURLやテキストをExtension側で取り出す方法が分からず、しばらく試行錯誤しました。

if let item = extensionContext?.inputItems.first as? NSExtensionItem,
   let provider = item.attachments?.first {
    provider.loadItem(forTypeIdentifier: "public.url")
}

extensionContextからNSExtensionItemを取り出し、そのattachmentsにあるNSItemProviderから目的のデータ型を指定して非同期に読み込む、という一連の流れを理解して初めて正しくデータを受け取れるようになりました。

4. Xcodeから直接デバッグ実行できず戸惑った

Extensionのコードを書き換えるたびに、動作確認の方法が分からず時間がかかっていました。

確認方法:
Extensionスキームを選択し、起動先アプリとしてホスト元アプリ(写真など)を指定して実行

Xcodeのスキーム選択でExtension用のターゲットを選び、実行時に起動するアプリとして共有元となるアプリ(写真アプリなど)を指定することで、ブレークポイントを使った通常のデバッグ実行ができることが分かりました。この方法を知ってから、動作確認の効率が大きく上がりました。

まとめ

  • Share Extensionはアプリ本体と分離された実行環境で、直接データやインスタンスを共有できない
  • 対応する共有データの種類はInfo.plistのNSExtensionActivationRuleで明示的に指定する必要がある
  • 受け取ったデータはNSExtensionItemとNSItemProviderを通じて非同期に取得する
  • Extension単体でもXcodeのスキーム設定で起動先アプリを指定すればデバッグ実行できる

アプリ本体とは別世界で動く仕組みだと理解してからは、データの受け渡し方法を素直に調べられるようになった実装でした。


本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。

コメント

タイトルとURLをコピーしました