iOS共享扩展程序在Chrome中无法使用 [英] iOS Share Extension is not working in 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 nameExtension
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屋!