iOS Share Extension:通过Safari中的上下文菜单共享页面的URL

sbi*_*nko 13 ios swift ios8-share-extension share-extension

我想要的是

我正在尝试实现以下用户流程:

  1. 用户正在iOS Safari中浏览网页.
  2. 用户选择一些内容(文本和图像)并等待上下文菜单出现.
  3. 用户选择"共享..."项.
  4. 用户从底部出现的共享菜单中选择我的App Extension.
  5. 所选内容和网页URL通过HTT呼叫共享给远程服务器.

我尝试了什么

我通过Xcode进行了Share扩展.这NSExtension是我的部分info.plist:

<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>
Run Code Online (Sandbox Code Playgroud)

这是test.js文件:

var GetURL = function() {};
GetURL.prototype = {
run: function(arguments) {
    arguments.completionFunction({"URL": document.URL});
}
};
var ExtensionPreprocessingJS = new GetURL;
Run Code Online (Sandbox Code Playgroud)

我期望得到以下结果:在viewDidLoad方法中extensionContext?.inputItems将为我提供几个输入项,通过它我将能够获得所选内容和Web URL.

出了什么问题

viewDidLoad方法中,extensionContext?.inputItems我只提供了一个项目 - 所选内容的纯文本表示(即使我同时选择了图像和文本).我可以使用纯文本,但我需要网页网址.

我的问题

如何在iOS Safari中使用共享扩展程序通过上下文菜单共享所选内容时,如何获取已打开网页的URL?

Joe*_*Joe 8

斯威夫特3

尝试以下方面的事情:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

"public.url"可以用kUTTypeURL从中导入的String 替换MobileCoreServices

  • 请注意,赏金已自动授予。“ itemProvider.hasItemConformingToTypeIdentifier(“ public.url”)`对我来说返回false。而`extensionContext?.inputItems`只包含一项-选择的纯文本表示形式-正是我在问题中描述的内容。 (3认同)

apb*_*apb 5

我花了一个下午的大部分时间来阅读有关此的文档并尝试不同的扩展排列,因为我正在寻找完全(我认为)您正在尝试做的事情。

我得出的结论是,在 iOS 上无法实现这种精确的流程。如果用户选择文本并使用上下文菜单(即“复制”、“查找”、“共享”...),您的扩展程序将收到的唯一NSItemProvider内容是他们选择的文本,即不是 plist与预处理 javascript 的结果。当他们从该菜单中选择共享时,当且仅当您在扩展文件的文件中NSExtensionActivationSupportsText设置为时,扩展才会显示。YESInfo.plist

根据docsNSExtensionActivationSupportsWebPageWithMaxCount,为了运行预处理 javascript,扩展必须设置为大于 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
Run Code Online (Sandbox Code Playgroud)

这意味着返回给扩展的 plist 对象同时具有页面的 URL 和 selectedText。

如果扩展的唯一目的是共享 URL,并且没有 URL 的纯文本不是一个合理的用例,那么您可能不应该NSExtensionActivationSupportsTextYES. 例如,像 Pocket 这样的应用程序启用了它,但是如果用户在 Safari 中选择了一些文本,然后尝试通过上下文菜单进行共享,则 Pocket 无法仅使用纯文本而没有页面 URL 执行任何有意义的操作,因此它只是弹出出现一个非常神秘的错误消息。

如果你想看一看,我也发布了我的扩展程序的代码