Process NSItemProvider data types in the Share (Swift) extension

I have a problem programming Share Extension in Swift (3).
My main problem is handling data type NSItemProvider.
Here's the problem: depending on the application from which I am running the extension, I get a different data type. For instance:
I say the application:

 let IMAGE_TYPE = kUTTypeImage as String if attachment.hasItemConformingToTypeIdentifier(IMAGE_TYPE){ attachment.loadItem(forTypeIdentifier: IMAGE_TYPE, options: nil){ data, error in ... } 

(Note: the attachment is of type NSItemProvider)

When executed from the Photos application, data is the URL, so I create a UIImage from this and continue with it.
The problem is that for some data applications there is already UIImage, and I cannot find how to do this.
It would probably be best to check the data type of the data object, but this is not trivial for me, at least.
Thanks in advance for your help!

+6
source share
1 answer

As far as I checked, in some cases you will have Data in Data . Thus, you may need to write something like this if you do not want to write an Objective-C wrapper for this method:

 if attachment.hasItemConformingToTypeIdentifier(IMAGE_TYPE) { attachment.loadItem(forTypeIdentifier: IMAGE_TYPE, options: nil) { data, error in let myImage: UIImage? switch data { case let image as UIImage: myImage = image case let data as Data: myImage = UIImage(data: data) case let url as URL: myImage = UIImage(contentsOfFile: url.path) default: //There may be other cases... print("Unexpected data:", type(of: data)) myImage = nil } //... } } 

(Not tested, you may need to fix some parts.)


In Objective-C, you can pass an Objective-C block by taking (UIImage *item, NSError *error) to completionHandler from loadItemForTypeIdentifier:options:completionHandler: In this case, the supplier of goods tries to convert all the image data of the view into UIImage .

NSItemProviderCompletionHandler

Discussion

...

element

The item to download. When specifying your block, set the type of this parameter to the specific data type that you want .... The item provider is trying to force data to the specified class.

So, if you don't mind writing any Objective-C wrapper, you can write something like this:

NSItemProvider + Swift.h:

 @import UIKit; typedef void (^NSItemProviderCompletionHandlerForImage)(UIImage *image, NSError *error); @interface NSItemProvider(Swift) - (void)loadImageForTypeIdentifier:(NSString *)typeIdentifier options:(NSDictionary *)options completionHandler:(NSItemProviderCompletionHandlerForImage)completionHandler; @end 

NSItemProvider + Swift.m:

 #import "NSItemProvider+Swift.h" @implementation NSItemProvider(Swift) - (void)loadImageForTypeIdentifier:(NSString *)typeIdentifier options:(NSDictionary *)options completionHandler:(NSItemProviderCompletionHandlerForImage)completionHandler { [self loadItemForTypeIdentifier:typeIdentifier options:options completionHandler:completionHandler]; } @end 

{YourProject} -Bridging-header.h:

 #import "NSItemProvider+Swift.h" 

And use it from Swift like:

  if attachment.hasItemConformingToTypeIdentifier(IMAGE_TYPE) { attachment.loadImage(forTypeIdentifier: IMAGE_TYPE, options: nil) { myImage, error in //... } } 

In my opinion, Apple should provide such an extension like NSItemProvider , you can write a function request using Apple Bug Reporter .

+7
source

Source: https://habr.com/ru/post/1015461/


All Articles