iOS共享扩展程序在Chrome中无法使用 [英] iOS Share Extension is not working in Chrome

查看:223
本文介绍了iOS共享扩展程序在Chrome中无法使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

适用于Safari,不适用于Chrome



也许这个问题很简单而且很愚蠢,但我是 iOS开发的新手,我找不到任何正确的解决方案来解决这个问题。


我需要获得:

1)page url <
2)页面名称

扩展名



strong> Info.plist

 < dict> 
< key> NSExtensionAttributes< / key>
< dict>
< key> NSExtensionActivationRule< / key>
< dict>
< key> NSExrensionActivationSupportsText< / key>
< true />
< key> NSExtensionActivationSupportsFileWithMaxCount< / key>
<整数> 1< /整数>
< key> NSExtensionActivationSupportsImageWithMaxCount< / key>
<整数> 1< /整数>
< key> NSExtensionActivationSupportsMovieWithMaxCount< / key>
<整数> 20< /整数>
< key> NSExtensionActivationSupportsWebPageWithMaxCount< / key>
<整数> 1< /整数>
< key> NSExtensionActivationSupportsWebURLWithMaxCount< / key>
<整数> 0< /整数>
< / 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



 覆盖func viewDidLoad(){
super.viewDidLoad()

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

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



$ let urlType = kUTTypePropertyList as String
if((itemProvider?.hasItemConformingToTypeIdentifier(urlType))!= nil){
itemProvider?.loadItemForTypeIdentifier(urlType,options:nil,completionHandler:{
(item:NSSecureCoding ?, error:NSError!) - >无效
如果让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
如果let attachments = item.attachments {
if!attachments.isEmpty {
itemProvider =(附件[0] as?NSItemProvider)!



$ b让urlType = kUTTypeURL作为NSString作为字符串

if((itemProvider?.hasItemConformingToTypeIdentifier(urlType)) !=
itemProvider?.loadItemForTypeIdentifier(urlType,options:nil,completionHandler:{
item,
中的错误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
如果let attachments = item.attachments {
if!attachments.isEmpty {
itemProvider =(附件[0] as?NSItemProvider)!
}
}
}

if self.linkUrl.characters.count< 1 {
if((itemProvider?.hasItemConformingToTypeIdentifier(public.url))!= nil){
itemProvider?.loadItemForTypeIdentifier(public.url,options:nil,completionHandler:{
item,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;


解决方案

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



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



这是我的扩展名.plist的一部分。我认为允许任意加载与共享无关,它是访问我的服务器所必需的,但我会把它放在这里作为参考。

 <密钥GT; NSAppTransportSecurity< /密钥GT; 
< dict>
< key> NSAllowsArbitraryLoads< / key>
< true />
< / dict>
< key> NSExtension< / key>
< dict>
< key> NSExtensionAttributes< / key>
< dict>
< key> NSExtensionActivationRule< / key>
< dict>
< key> NSExtensionActivationSupportsImageWithMaxCount< / key>
<整数> 1< /整数>
< key> NSExtensionActivationSupportsWebURLWithMaxCount< / key>
<整数> 1< /整数>
< / 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让provider =(context.inputItems.first?.attachments as?[NSItemProvider])?.如果provider.hasItemConformingToTypeIdentifier( kUTTypeURL as String){
provider.loadItemForTypeIdentifier(kUTTypeURL as String,options:nil){url,错误
guard让url = url as? NSURL else {return self.cancel()}
//根据网址做你想做的事
}
} else {
cancel()
}
}
}

至于获取网站的名称,认为。一种是使用您已经在项目中使用的JS脚本,另一种是查看提供程序是否具有文本类型的项目(包含站点名称),但它们是浏览器特定的项目(某些仅适用于Safari,一些适用于浏览器像Chrome)。我选择以不同的方式进行讨论,我使用了伪造的WKWebView(它永远不会被添加到视图层次结构中,它只是一个属性),并使用我从提供者处获得的URL发出请求。然后,我可以从它的JS代码拦截站点名称,如下所示:

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

func setupForURL(url:NSURL){
(...)
hiddenWebView ??.Request(NSURLRequest(URL:url))
}

// MARK: - WKNavigationDelegate
扩展ShareView:WKNavigationDelegate {
func webView(webView:WKWebView, didFinishNavigation导航:WKNavigation!){
webView.evaluateJavaScript(document.title){结果,
中的错误让title = result as? String else {return}
//根据页面的标题做你想做的事情
}
}
}


Works for Safari, Doesn't work for Chrome

Maybe the question is simple and stupid but I am new to iOS Development and I cannot find any right solution to solve this issue.

I need to get:
1) page url
2) page name

Extension

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>

I've added more to Chrome but it still does not work. For Safari, this is enough:

NSExtensionActivationSupportsWebPageWithMaxCount, NSExtensionActivationSupportsWebURLWithMaxCount, NSExrensionActivationSupportsText, NSExtensionJavaScriptPreprocessingFile

I try three approaches, with and without DemoPreprocessor.js. But all don't work for 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;

解决方案

In my app I've made it work, however it was some time ago and I don't remember which exact steps are necessary, so I'll post my setup in hopes it will serve as a drop in solution.

The first issue I see in your plist is a 0 count for WebURLs.

This is a part of my extension's .plist. I think that allowing arbitrary loads has nothing to do with sharing and it was needed for accessing my server, nevertheless I'll put it here for reference.

<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>

My controller's part of code responsible for getting a 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()
        }
    }
}

As for getting the site's name, well there are a few ways I think. One is to use the JS script that you already have in your project, another is to see whether the provider has an item with a text type (containing the site's name) but they are browser specific (some work only for Safari, some for browsers like Chrome). I chose to go about it in a different way, I use a fake WKWebView (which is never added to view hierarchy, it's just a property) and make a request with the url that I got from the provider. Then I'm able to intercept the site's name from it's JS code like so:

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

这篇关于iOS共享扩展程序在Chrome中无法使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆