Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 Share extension loadItemForTypeIdentifier:options:completionHandler: completion closure not executing

I'm using the loadItemForTypeIdentifier:options:completionHandler: method on an NSItemProvider object to extract a url from Safari via a Share extension in iOS 8.

In Objective-C, this code and works and the block runs.

[itemProvider loadItemForTypeIdentifier:(@"public.url" options:nil completionHandler:^(NSURL *url, NSError *error) {
    //My code
}];

In Swift, it looks very similar, however the closure doesn't run. Also, itemProvider.hasItemConformingToTypeIdentifier("public.url") returns YES so there must be a valid object to parse the url from inside the itemProvider.

itemProvider.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: { (urlItem, error) in
    //My code
})

The Info.plist NSExtension portion is exactly the same for both Objective-C and Swift version and looks like this:

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
        <key>NSExtensionPointName</key>
        <string>com.apple.share-services</string>
        <key>NSExtensionPointVersion</key>
        <string>1.0</string>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
</dict>

What am I doing wrong?

like image 234
abc123 Avatar asked Jun 16 '14 02:06

abc123


2 Answers

call

self.extensionContext!.completeRequestReturningItems([], completionHandler: nil) 

at the end of completionHandler instead of calling it at the end of didSelectPost()

like image 140
pJes2 Avatar answered Oct 21 '22 21:10

pJes2


Since completeRequestReturningItems must be called after all completionHandlers are called back, below is what I do.

 let group = dispatch_group_create()

    for item: AnyObject in self.extensionContext!.inputItems {
        let inputItem = item as! NSExtensionItem
        for provider: AnyObject in inputItem.attachments! {
            let itemProvider = provider as! NSItemProvider
            if itemProvider.hasItemConformingToTypeIdentifier("public.url") {
                dispatch_group_enter(group)
                itemProvider.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: {
                    (result: NSSecureCoding!, error: NSError!) -> Void in
                    //...
                    dispatch_group_leave(group)
                });
            }
            if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
                dispatch_group_enter(group)
                itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, completionHandler: { (result, error) -> Void in
                    if let resultURL = result as? NSURL {
                        if let image = UIImage(data: NSData(contentsOfURL: resultURL)!) {
                            // ...
                        }
                    }
                    dispatch_group_leave(group)
                });
            }
        }
    }
    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
        self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
    })
like image 40
hebinda Avatar answered Oct 21 '22 19:10

hebinda