Расширение рассылки iOS: получите URL-адрес страницы при совместном использовании через контекстное меню в Safari
Что я хочу
Я пытаюсь выполнить следующий поток пользователей:
- Пользователь просматривает веб-страницу в Safari iOS.
- Пользователь выбирает какой-либо контент (текст и изображения) и ожидает появления контекстного меню.
- Пользователь выбирает элемент "Поделиться...".
- Пользователь выбирает мое расширение приложения в меню совместного доступа, которое появляется внизу.
- Выбранный контент и URL-адрес веб-страницы передаются на удаленный сервер через HTT-вызов.
Что я пробовал
Я сделал расширение Share через Xcode. Здесь раздел NSExtension
моего info.plist
:
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionJavaScriptPreprocessingFile</key>
<string>test</string>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>
</dict>
Здесь файл test.js
:
var GetURL = function() {};
GetURL.prototype = {
run: function(arguments) {
arguments.completionFunction({"URL": document.URL});
}
};
var ExtensionPreprocessingJS = new GetURL;
Я ожидал следующего результата: в viewDidLoad
метод extensionContext?.inputItems
предоставил мне несколько элементов ввода, через которые я смог бы получить выбранный контент и веб-URL.
Что не так.
В viewDidLoad
метод extensionContext?.inputItems
предоставляет мне только один элемент - простое текстовое представление выбранного содержимого (даже когда я выбрал изображения и текст одновременно). Я могу жить с открытым текстом, но мне нужен URL-адрес веб-страницы.
Мой вопрос
Как я могу получить URL-адрес открытой веб-страницы при использовании расширения Share для совместного использования выбранного контента через контекстное меню в iOS Safari?
Ответы
Ответ 1
Я провел довольно сложную часть дня, читая документы по этому поводу, и пробовал разные перестановки расширений, поскольку я искал точно (я думаю), что вы пытались сделать.
Я пришел к выводу, что этот точный поток не может быть достигнут на iOS. Если пользователь выбирает текст и использует контекстное меню (например, "Копировать", "Смотри вверх", "Поделиться"...), единственное, что когда-либо будет получать ваше расширение - это NSItemProvider
с текстом, который они выбрали, т.е. а не plist с результатами предварительной обработки javascript. Когда они выбирают "Поделиться" из этого меню, расширение появляется тогда и только тогда, когда вы установили NSExtensionActivationSupportsText
в YES
в файле расширения Info.plist
.
Чтобы запустить javascript предварительной обработки, расширение должно иметь NSExtensionActivationSupportsWebPageWithMaxCount
установить значение больше 0, в docs, Если расширение вызывается через выбранное контекстное меню, этот файл javascript никогда не запускается.
Однако можно получить довольно близкое к желаемому потоку. Если пользователь находится в Safari и выбирает какой-то текст, а затем вместо нажатия "Share" в контекстном меню кратковременно нажимает значок "Share" в нижней части пользовательского интерфейса Safari, тогда NSItemProvider
возвращается как plist и NSExtensionJavaScriptPreprocessingFile
запускается. Мой файл 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-адрес страницы, так и выбранный текст.
Если единственной целью расширения является URL-адрес общего доступа, а обычный текст без URL-адреса не является разумным вариантом использования, вы, вероятно, не должны иметь NSExtensionActivationSupportsText
, установленный в YES
. Например, такое приложение, как Pocket, разрешено, но если пользователь выбирает какой-либо текст в Safari и затем пытается поделиться через контекстное меню, Pocket не может делать ничего значимого только с открытым текстом и без URL-адреса страницы, поэтому он просто появляется вверх довольно загадочное сообщение об ошибке.
Я опубликовал код для моего расширения, если вы хотите посмотреть.
Ответ 2
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"
можно заменить на строку kUTTypeURL
, импортированную из MobileCoreServices