Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS共享扩展:在Safari中通过上下文菜单共享时获取页面的URL_Ios_Swift_Ios8 Share Extension_Share Extension - Fatal编程技术网

iOS共享扩展:在Safari中通过上下文菜单共享时获取页面的URL

iOS共享扩展:在Safari中通过上下文菜单共享时获取页面的URL,ios,swift,ios8-share-extension,share-extension,Ios,Swift,Ios8 Share Extension,Share Extension,我想要什么 我正在尝试实现以下用户流: 用户正在iOS Safari中浏览网页。 用户选择一些内容文本和图像,并等待上下文菜单出现。 用户选择共享。。。项目 用户在从底部弹出的共享菜单中选择我的应用程序扩展。 所选内容和网页URL通过HTT调用共享给远程服务器。 我试过的 我通过Xcode做了一个共享扩展。这是我的info.plist的NSExtension部分: 我期望得到以下结果:在viewDidLoad方法extensionContext?中,inputItems将为我提供几个输入项,通过

我想要什么

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

用户正在iOS Safari中浏览网页。 用户选择一些内容文本和图像,并等待上下文菜单出现。 用户选择共享。。。项目 用户在从底部弹出的共享菜单中选择我的应用程序扩展。 所选内容和网页URL通过HTT调用共享给远程服务器。 我试过的

我通过Xcode做了一个共享扩展。这是我的info.plist的NSExtension部分:

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

出了什么问题

在viewDidLoad方法extensionContext?.inputItems中,仅为我提供一项—所选内容的纯文本表示,即使我同时选择了图像和文本。我可以接受纯文本,但我需要网页URL

我的问题

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

Swift 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)
        }
    }
}

public.url可以替换为从MobileCoReserves导入的kUTTypeURL字符串

我花了一个下午的时间阅读了关于这个的文档,并尝试了不同的扩展排列,就像我想做的一样,我想你正试图做的那样

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

为了运行预处理javascript,扩展必须将NextensionActivationSupportsWebPageWithMaxCount设置为大于0的值。如果通过所选文本上下文菜单调用扩展名,则该javascript文件永远不会运行

但是,可以非常接近所需的流。如果用户在Safari中,并选择了一些文本,然后点击Safari UI底部的共享图标,而不是点击上下文菜单中的共享,那么NSItemProvider将作为plist返回,NSExtensionJavaScriptPreprocessFile将运行。我的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来做任何有意义的事情,所以它只会弹出一条相当隐晦的错误消息


如果您想看一看,我也会看一看。

这应该是公认的答案,在应用Swfit3语法后,它对我有效:itemProvider.loadItemforTypeIdentifier:public.url,选项:nil,completionHandler:{url,错误->无效in@YunCHEN感谢您的提示。更新了swift 3的答案请注意,奖金已自动授予。itemProvider.hasItemConformingToTypeIdentifierpublic.url为我返回false。而extensionContext?。inputItems仅包含一个项目-选择的纯文本表示-正是我在n my question.hi,docx/pdf有什么解决方案吗?感谢Docs帮助克服上述问题:
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)
        }
    }
}
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