欲しいもの
私は次のユーザーフローを達成しようとしています:
私が試したこと
Xcodeを介してShare拡張機能を作成しました。これが私のinfo.plist
のNSExtension
セクションです。
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionJavaScriptPreprocessingFile</key>
<string>test</string>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
<key>NSExtensionPointIdentifier</key>
<string>com.Apple.share-services</string>
</dict>
test.js
ファイルは次のとおりです。
var GetURL = function() {};
GetURL.prototype = {
run: function(arguments) {
arguments.completionFunction({"URL": document.URL});
}
};
var ExtensionPreprocessingJS = new GetURL;
次の結果を期待していました。viewDidLoad
メソッドでextensionContext?.inputItems
はいくつかの入力項目を提供し、それを介して選択したコンテンツとWebURLを取得できます。
何がうまくいかない
viewDidLoad
メソッドではextensionContext?.inputItems
は、選択したコンテンツのプレーンテキスト表現(画像とテキストを同時に選択した場合でも)という1つのアイテムのみを提供します。プレーンテキストで生活できますが、ウェブページのURLが必要です。
私の質問
IOS Safariのコンテキストメニューを介して選択したコンテンツを共有するために共有拡張機能を使用する場合、開いたWebページのURLを取得するにはどうすればよいですか?
私はあなたがやろうとしていたことを正確に(私は思う)やろうとしていたので、これに関するドキュメントを読んで、拡張機能のさまざまな順列を試し、午後の恥ずかしいほど大部分を費やしました。
私は、この正確なフローはiOSでは達成できないと結論付けました。ユーザーがテキストを選択してコンテキストメニュー(つまり、「コピー」、「ルックアップ」、「共有」など)を使用する場合、拡張機能が受け取るのは、テキストを含むNSItemProvider
だけです。選択されています。つまり、前処理javascriptの結果を含むplistではありません。そのメニューから[共有]を選択すると、拡張機能のInfo.plist
ファイルでNSExtensionActivationSupportsText
がYES
に設定されている場合にのみ、拡張機能が表示されます。
前処理JavaScriptを実行するには、拡張機能でNSExtensionActivationSupportsWebPageWithMaxCount
を docs に従って0より大きい値に設定する必要があります。選択したテキストコンテキストメニューから拡張機能が呼び出された場合、そのjavascriptファイルは実行されません。
ただし、目的のフローにかなり近づくことは可能です。ユーザーがSafariを使用していて、テキストを選択し、コンテキストメニューで[共有]をタップする代わりに、Safari UIの下部にある[共有]アイコンをタップすると、NSItemProvider
がplistとNSExtensionJavaScriptPreprocessingFile
が実行されます。私のJavaScriptファイルは次のようになります。
var Share = function() {};
Share.prototype = {
run: function(arguments) {
arguments.completionFunction({"URL": document.URL, "selectedText": document.getSelection().toString()});
},
finalize: function(arguments) {
// alert shared!
}
};
var ExtensionPreprocessingJS = new Share
これは、拡張機能に返されるplistオブジェクトに、ページのURLとselectedTextの両方があることを意味します。
拡張機能の唯一の目的がURLの共有であり、URLのないプレーンテキストが意味のある使用例ではない場合は、NSExtensionActivationSupportsText
をYES
に設定しないでください。たとえば、Pocketのようなアプリでは有効になっていますが、ユーザーがSafariでテキストを選択し、コンテキストメニューから共有しようとすると、PocketはプレーンテキストだけでページURLがないと意味のあることを何もできないため、ポップするだけです。かなり不可解なエラーメッセージが表示されます。
私は 私の拡張機能のコードを公開しました もご覧になりたい場合は。
Swift
次の線に沿って何かを試してください:
override func didSelectPost() {
if let item = extensionContext?.inputItems.first as? NSExtensionItem,
let itemProvider = item.attachments?.first as? NSItemProvider,
itemProvider.hasItemConformingToTypeIdentifier("public.url") {
itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil) { (url, error) in
if let shareURL = url as? URL {
// do what you want to do with shareURL
}
self.extensionContext?.completeRequest(returningItems: [], completionHandler:nil)
}
}
}
"public.url"
は、kUTTypeURL
からインポートされたMobileCoreServices
文字列に置き換えることができます。