Расширение расширения iOS не работает в Chrome
Работает для Safari, не работает для Chrome
Возможно, вопрос простой и глупый, но я новичок в iOS Development, и я не могу найти правильное решение для решения этой проблемы.
Мне нужно получить:
1) URL-адрес страницы 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;
Ответы
Ответ 1
В моем приложении я сделал его работу, однако это было какое-то время назад, и я не помню, какие именно шаги необходимы, поэтому я буду размещать свои настройки в надежде, что это станет падением в решении.
Первая проблема, которую я вижу в вашем plist, равна 0 для WebURL.
Это часть моего расширения .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 script, который у вас уже есть в вашем проекте, а другой - посмотреть, есть ли у провайдера элемент с типом текста (содержащий имя сайта), но они специфичны для браузера (некоторые работают только для Safari, некоторые для браузеров, таких как Chrome). Я решил пойти по-другому, я использую поддельный 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 title
}
}
}
Ответ 2
Добавьте NSExtensionActivationSupportsText и NSExtensionActivationSupportsWebPageWithMaxCount в NSExtensionActivationRule с типом как Number и установите для них значение 1.
Это было для меня.