You are probably calling getImageFromExtension from didSelectPost . At the end of didSelectPost you should call completeRequestReturningItems:completionHandler: to tell the host application to complete the application extension request using an array of results. When this method is called, the entire ShareViewController is rejected and freed. When you call this at the end of didSelectPost , it starts before NSItemProvider can get the image URL. Because it happens asynchronously. To fix this, you should call completeRequestReturningItems:completionHandler: after NSItemProvider selected imageURL.
Here's how it should work:
- (void)didSelectPost { NSString *typeIdentifier = (NSString *)kUTTypeImage NSExtensionItem *item = self.extensionContext.inputItems.firstObject; NSItemProvider *itemProvider = item.attachments.firstObject; if ([itemProvider hasItemConformingToTypeIdentifier:typeIdentifier]) { [itemProvider loadItemForTypeIdentifier:typeIdentifier options:nil completionHandler:^(NSURL *url, NSError *error) { NSURL *imageURL = (NSURL *)item self.saveImage(imageURL) [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; }]; } }
By the way, there is no need to use dispatch_async when working with NSItemProvider, since the provider is already performing its work asynchronously.
I wrote a blog post about this if you want to read a little more about it.
EDIT
Now you can upload the image using the path to the file you just extracted. This only works in extension! If you want to access the image from the containing application, you cannot use the file URL you just received. The sharing extension saves the selected image in a folder inaccessible to the contained application.
To make the image available to the containing application, you need to activate App Groups in your application and extension. Then the extension saves the image in a common container, and the containing application can receive it:
func saveImage(url: NSURL) { guard let imageData = NSData(contentsOfURL: url) else { return } let selectedImage = UIImage(data: imageData) let fileManager = NSFileManager.defaultManager() if let sharedContainer = fileManager.containerURLForSecurityApplicationGroupIdentifier("YOUR_GROUP_IDENTIFIER") { if let dirPath = sharedContainer.path { let sharedImageFilePath = dirPath + "/image.png" let binaryImageData = UIImagePNGRepresentation(selectedImage!) binaryImageData?.writeToFile(sharedImageFilePath, atomically: true)
source share