Search code examples
iosobjective-cxcodeios-app-extension

App Extension iOS9: How can I send a string / URL from the share view to my the app?


Unfortunately, there's currently a lack of sample code oder proper information on App Extension / Share Sheets on iOS 9. (Even Apples Dev Support is very disappointing in this regard. Just today I got the answer "We don’t have an action extension sample either unfortunately". And they won't send me.

Anyway, maybe someone is willing to share his knowledge on this topic. So, adding a Share Extension in xcode is the easy part, but I struggle with

  1. sending and receiving strings: I want the Share Sheet to open in Safari with the current URL (maybe even with the Character Counter like in the WWDC 2015 Video "App Extension Best Practices") and send it to the app by tapping "Post". Is it really necessary to open an NSURLSession?

  2. adding an Share-icon under / General / "App Icons and Launch Images" / App Icons Source is not possible. Some Sources suggest to use Asset Catalog - but before I do, is there no other way to simply add ONE image?

Other Sources I found include:

Today Extension: raywenderlich.com/83809/ios-8-today-extension-tutorial

How to Build a Simple Action Extension: http://code.tutsplus.com/tutorials/ios-8-how-to-build-a-simple-action-extension--cms-22794

Basic Share Extensions with Data Sharing on iOS 8: http://www.andypierz.com/blog/2014/9/19/basic-share-extensions-with-data-sharing-on-ios-8

What I was able to accomplish so far is to add a title to the Share Sheet on shareViewController.m:

- (void)loadView
{
    [super loadView];
    self.title = @"Title of the Share Sheet";
}

Solution

  • to extract the URL, you will have to enable the ExtensionPreprocessingJS part first

    the following is slightly modified from AppCode iOS8 action extension tutorial

    Add a new file GetURL.js to your share extension folder

    var GetURL = function() {};
    
    GetURL.prototype = {
    
       run: function(arguments) {
           arguments.completionFunction({ "currentUrl" : document.URL });
       }    
    };
    
    var ExtensionPreprocessingJS = new GetURL;
    

    Next, you will have to edit your Info.plist so that the host app will call the JS. Refer to AppCode tutorial on how to do so. enter image description here

    Then include the following function in your ShareViewController viewDidLoad

        //swift code
        let extensionItem = extensionContext?.inputItems.first as! NSExtensionItem
        let itemProvider = extensionItem.attachments?.first as! NSItemProvider
    
        let propertyList = String(kUTTypePropertyList)
        if itemProvider.hasItemConformingToTypeIdentifier(propertyList) {
            itemProvider.loadItemForTypeIdentifier(propertyList, options: nil, completionHandler: { (item, error) -> Void in
                let dictionary = item as! NSDictionary
                NSOperationQueue.mainQueue().addOperationWithBlock {
                    let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as! NSDictionary
                    let url = NSURL(string: (results["currentURL"] as! String))                                        
                    //now you can do what you like with this url
                }
            })
        } else {
            print("error")
        }