iOS 共享扩展在 Chrome 中不起作用

Posted

技术标签:

【中文标题】iOS 共享扩展在 Chrome 中不起作用【英文标题】:iOS Share Extension is not working in Chrome 【发布时间】:2016-07-28 13:14:03 【问题描述】:

适用于 Safari,不适用于 Chrome

也许这个问题既简单又愚蠢,但我是 iOS 开发 的新手,我找不到任何合适的解决方案来解决这个问题。

我需要得到: 1) 页面网址 2) 页面名称

扩展

Info.plist

<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExrensionActivationSupportsText</key>
            <true/>
            <key>NSExtensionActivationSupportsFileWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsImageWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsMovieWithMaxCount</key>
            <integer>20</integer>
            <key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>0</integer>
        </dict>
        <key>NSExtensionjavascriptPreprocessingFile</key>
        <string>DemoPreprocessor</string>
    </dict>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
</dict>

我在 Chrome 中添加了更多内容,但仍然无法正常工作。对于 Safari,这就足够了:

NSExtensionActivationSupportsWebPageWithMaxCount, NSExtensionActivationSupportsWebURLWithMaxCount, NSExrensionActivationSupportsText, NSExtensionJavaScriptPreprocessingFile

我尝试了三种方法,使用和不使用 DemoPreprocessor.js。但都不适用于 Chrome:

1。 ShareViewController.swift

override func viewDidLoad() 
    super.viewDidLoad()

    let items = extensionContext?.inputItems
    var itemProvider: NSItemProvider?

    if items != nil && items!.isEmpty == false 
        let item = items![0] as! NSExtensionItem
        if let attachments = item.attachments 
            if !attachments.isEmpty 
                itemProvider = (attachments[0] as? NSItemProvider)!
            
        
    

    let urlType = kUTTypePropertyList as String
    if ((itemProvider?.hasItemConformingToTypeIdentifier(urlType)) != nil) 
        itemProvider?.loadItemForTypeIdentifier(urlType, options: nil, completionHandler: 
            (item: NSSecureCoding?, error: NSError!) -> Void in
            if let resultDict = item as? NSDictionary 
                self.linkName = resultDict[NSExtensionJavaScriptPreprocessingResultsKey]!["URL"] as! String
                self.linkUrl = resultDict[NSExtensionJavaScriptPreprocessingResultsKey]!["title"] as! String
            

        )
    


2 ShareViewController.swift

override func viewDidLoad() 
    super.viewDidLoad()

    let items = extensionContext?.inputItems
    var itemProvider: NSItemProvider?

    if items != nil && items!.isEmpty == false 
        let item = items![0] as! NSExtensionItem
        if let attachments = item.attachments 
            if !attachments.isEmpty 
                itemProvider = (attachments[0] as? NSItemProvider)!
            
        
    

    let urlType = kUTTypeURL as NSString as String

    if ((itemProvider?.hasItemConformingToTypeIdentifier(urlType)) != nil) 
       itemProvider?.loadItemForTypeIdentifier(urlType, options: nil, completionHandler: 
           item, error in
           self.linkName = self.contentText
           self.linkUrl = "\(item!)"
       )
    


3 ShareViewController.swift

override func viewDidLoad() 
    super.viewDidLoad()

    let items = extensionContext?.inputItems
    var itemProvider: NSItemProvider?

    if items != nil && items!.isEmpty == false 
        let item = items![0] as! NSExtensionItem
        if let attachments = item.attachments 
            if !attachments.isEmpty 
                itemProvider = (attachments[0] as? NSItemProvider)!
            
        
    

    if self.linkUrl.characters.count < 1 
        if ((itemProvider?.hasItemConformingToTypeIdentifier("public.url")) != nil) 
            itemProvider?.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: 
                item, error in self.linkUrl = "\(item!)"
            )
        
    


DemoPreprocessor.js

var MyPreprocessor = function() ;

MyPreprocessor.prototype = 
    run: function(arguments) 
        arguments.completionFunction("URL": document.URL, "pageSource": document.documentElement.outerhtml, "title": document.title, "selection": window.getSelection().toString());
    
;

var ExtensionPreprocessingJS = new MyPreprocessor;

【问题讨论】:

@EricD 我需要删除 swift 标签吗? @EricD 我认为 plist - manifest、ShareViewController.swift、DemoPreprocessor.js 是相关的,因为我阅读了一些文档、问题、答案并且人们在那里写道,一些组合有效(使用 PreprocessingJS,有些没有,使用不同的 NSExtensionActivationRule)。但是我尝试的所有东西都只能在 Safari 中工作,而不能在 Chrome 中工作 【参考方案1】:

在我的应用程序中我已经让它工作了,但是那是前一段时间了,我不记得哪些确切的步骤是必要的,所以我会发布我的设置,希望它可以作为一个解决方案。

我在您的 plist 中看到的第一个问题是 WebURL 计数为 0。

这是我的扩展的 .plist 的一部分。我认为允许任意加载与共享无关,访问我的服务器需要它,但我将其放在这里以供参考。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsImageWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
    <key>NSExtensionPrincipalClass</key>
    <string>ShareViewController</string>
</dict>

我的控制器负责获取 URL 的代码部分:

// MARK: - NSExtensionRequestHandling
extension ShareViewController 
    override func beginRequestWithExtensionContext(context: NSExtensionContext) 
        super.beginRequestWithExtensionContext(context)

        guard let provider = (context.inputItems.first?.attachments as? [NSItemProvider])?.first else  return cancel() 

        if provider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) 
            provider.loadItemForTypeIdentifier(kUTTypeURL as String, options: nil)  url, error in
                guard let url = url as? NSURL else  return self.cancel() 
                // do what you want with the url
            
         else 
            cancel()
        
    

至于获得网站的名称,我认为有几种方法。一种是使用您在项目中已有的 JS 脚本,另一种是查看提供者是否有一个文本类型的项目(包含站点名称)但它们是特定于浏览器的(有些仅适用于 Safari,有些适用于浏览器像铬)。我选择了另一种方式,我使用了一个假的 WKWebView (它从未添加到视图层次结构中,它只是一个属性)并使用我从提供者那里获得的 url 发出请求。然后我可以从它的 JS 代码中截取网站的名称,如下所示:

func setupHiddenWebView() 
    hiddenWebView = WKWebView()
    hiddenWebView?.navigationDelegate = self


func setupForURL(url: NSURL) 
    (...)
    hiddenWebView?.loadRequest(NSURLRequest(URL: url))


// MARK: - WKNavigationDelegate
extension ShareView: WKNavigationDelegate 
    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) 
        webView.evaluateJavaScript("document.title")  result, error in
            guard let title = result as? String else  return 
            // do what you want with the page's title
        
    

【讨论】:

你能澄清一下代码吗? hiddenWebview 没有声明,(...) 不清楚,也不清楚你为什么要使用扩展,你到底在扩展什么,以及出于什么原因。谢谢!【参考方案2】:

在 NSExtensionActivationRule 下添加 NSExtensionActivationSupportsText 和 NSExtensionActivationSupportsWebPageWithMaxCount,类型为 Number 并设置为 1。

这就是为我做的。

【讨论】:

NSExtensionActivationSupportsText 应设置为布尔值 &lt;true/&gt; 而不是数字

以上是关于iOS 共享扩展在 Chrome 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 扩展程序 - 在新打开的选项卡中不起作用

chrome.notifications.onClosed 在 google chrome 扩展的 background.js 中不起作用

为啥 jscript 在 iOS 7 的 Chrome 浏览器中不起作用?

mailto 链接在 chrome 扩展弹出窗口中不起作用

window.scrollTo 在 iOS chrome 中不起作用

Android - Branch.io 深度链接在 chrome 中不起作用