Danny Wong
Danny Wong

Reputation: 11

Action extension loadItemForTypeIdentifier returns UIImage instead of NSURL

I am working on an app that can show image metadata and share the image without the metadata. My app also has action extension that can view metadata.

When I try to share an image within my app using the share sheet, and select the action extension of my own app, I noticed that loadItemForTypeIdentifier doesn't return the NSURL, instead it is giving me an UIImage. Is there anyway that I can force the return type as NSURL?

if let itemProvider = extensionItem.attachments?[0] as? NSItemProvider {
    //println("\(itemProvider.description)")
    if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
        // This is an image. We'll load it, then place it in our image view.
        itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, completionHandler: { (item, error) -> Void in                    
            if let photoURL = item as? NSURL {
                NSOperationQueue.mainQueue().addOperationWithBlock {
                    self.fetchPhotoMetadata(photoURL)

                    let imageData = NSData(contentsOfURL: photoURL)
                    self.imageView.image = UIImage(data: imageData!)
                }
            } 
        })
    }

In Apple's documentation, it says for "item"

The item to be loaded. When specifying your block, set the type of this parameter to the specific data type you want. For example, when requesting text data, you might set the type to NSString or NSAttributedString. The item provider attempts to coerce the data to the class you specify.

When I try to specify the return type in the closure as (item: NSURL!, error: NSError!) -> Void ..., I got the following error

Cannot invoke 'loadItemForTypeIdentifier' with an argument list of type '(String, options: nil, completionHandler: (NSURL!, NSError!) -> Void)'

    if let itemProvider = extensionItem.attachments?[0] as? NSItemProvider {
        //println("\(itemProvider.description)")
        if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
            // This is an image. We'll load it, then place it in our image view.
            itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, completionHandler: { (item: NSURL!, error: NSError!) -> Void in                    
                if let photoURL = item as? NSURL {
                    NSOperationQueue.mainQueue().addOperationWithBlock {
                        self.fetchPhotoMetadata(photoURL)

                        let imageData = NSData(contentsOfURL: photoURL)
                        self.imageView.image = UIImage(data: imageData!)
                    }
                } 
            })
        }

Has anyone here encounter the similar issue?

Upvotes: 0

Views: 1452

Answers (2)

Asadullah Ali
Asadullah Ali

Reputation: 1064

Use kUTTypeURL instead of kUTTypeImage in these both statements

if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
            // This is an image. We'll load it, then place it in our image view.
            itemProvider.loadItemForTypeIdentifier(kUTTypeURL as String, options:

Upvotes: 0

Rupert Rawnsley
Rupert Rawnsley

Reputation: 2659

It appears that the shared attachment can take the form of an NSURL or a UIImage depending on the context it is launched from. I am inferring this from a Monotouch port that has been modified to handle this possibility. Sadly this change is absent from the original Apple sample code.

Once you have registered a share extension, it appears that this code is called in preference to the application.openURL method that was previously the entry point for registered document types. This is invoked in the context of your own application with richer access to the shared object data (hence the UIImage), whereas share extensions appear to be based around a common NSURL written by the host app to some sort of sandboxed DMZ.

I'm sure this is not the whole story, but the Apple documentation is frustratingly opaque.

Upvotes: 0

Related Questions