[Swift] iOS の共有メニューに追加できるアプリを作る(その1:共有メニューにアプリが表示されるまで)
Sponsor Link
何を受け取り可能とするか?:Info.plistの設定
Info.plistで、どのようなデータを受け付け可能とするかを設定します。
Xcodeのテンプレートでは、全てを受け付けるようになっています。
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsSupported</key>
<array></array>
<key>NSExtensionActivationRule</key>
<string>TRUEPREDICATE</string> <- 受け付け可能設定
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>
</dict>
Appleのドキュメントの”NSExtensionActivationRule”のセクションを参考に、受け付けたいタイプを設定していきます。
今回は、イメージとWebPageを受け取りたいので、以下を設定します。
- NSExtensionActivationSupportsImageWithMaxCount
- NSExtensionActivationSupportsWebPageWithMaxCount
指定するのは、最大受付数なので、TRUE/FALSEを設定するものではありません。
以下のようになります。
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsSupported</key>
<array></array>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<integer>1</integer>
</dict>
</dict>
HostAppからデータを受け取る
Xcodeのテンプレートとして作成されたShareViewControllerで、プロパティ extensionContext 経由でデータを受け取ることができます。
以下は、ShareViewController#didSelectPostに記述したコードです。
override func didSelectPost() {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
let checkItems = self.extensionContext?.inputItems // ⬅︎
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
extensionContent.inputItems は、NSExtensionItem の配列で、このデータが、HostAppから渡されたデータです。
Item の attachements が、NSItemProvider の配列となっています。実データは、この NSItemProvider 経由で受け取ることとなります。
最初に設定した受け付けるタイプの種類と数がこの NSItemProvider とその attachments に反映されます。
異なるタイプの情報を受け取れるようにすると(かつHostApp側から渡そうとすると)複数の NSItemProvider が渡されます。
同一タイプの複数の要素を受け取れるようにすると(例:複数枚の画像)、NSItemProvider の attachments が複数セットされてきます。
また、NSItemProvider#hasItemConformingToTypeIdentifier にて、欲しいタイプの情報を含んでいるか確認することができます。
例えば、画像データを入手したい時には、以下のようにすることで、HostApp側からの情報を取得できます。
override func didSelectPost() {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
guard let checkItems = self.extensionContext?.inputItems else { return }
guard let extensionItem = checkItems[0] as? NSExtensionItem else { return }
guard let firstItem = extensionItem.attachments?.first! else { return }
if firstItem.hasItemConformingToTypeIdentifier(String(kUTTypeJPEG)) {
firstItem.loadItem(forTypeIdentifier: String(kUTTypeJPEG), options: nil) { (item, error) in
// process item as it is a path to jpeg file
print("\(item)")
}
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
}
説明は以上です。
HostAppからデータを取得できるようになりましたが、以下の項目の検討も必要です。
- 自分のアプリとApp Extension でのコード共有
- App Extension で使えるAPIの確認
[Swift] iOS の共有メニューに追加できるアプリを作る(その3:ContainingApp と App Extensionのデータ共有)
Sponsor Link
[…] 続きの説明は、こちら。 […]