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:
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
}
})
}
}
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!)"
})
}
}
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;
You can use Chrome extensions on iPhone via the Chrome Remote Desktop app for iPhone and iPad. For the uninitiated, it is an app that allows you to securely access your computer from your iOS device.
View and add Safari extensionsGo to Settings > Safari, then tap Extensions. Tap More Extensions to browse extensions from the App Store. When you find one you want, tap the price, or if the app is free, tap Get, then follow the onscreen instructions.
Share Extension is an easy way that Apple provides to share contents (images, audio, files, etc.) from one app to another, even made by different developers.
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
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With