在Share Extension(Swift)中处理NSItemProvider数据类型

时间:2017-03-04 01:19:19

标签: ios swift uiimage nsdata

我在 Swift (3)中遇到分享扩展程序编程问题。
我的主要问题是处理 NSItemProvider data类型。
问题在于:根据我启动扩展程序的应用程序,我得到了不同类型的数据。例如:
我告诉申请:

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

(注意:附件的类型为 NSItemProvider

从照片应用程序执行时,data是一个URL,因此我从中创建了一个UIImage并继续使用。
问题是,对于某些应用程序data已经是UIImage,我无法找到如何区分大小写。
最好的方法可能是检查data对象的数据类型,但至少对我来说这并不简单。
在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:14)

据我测试,在某些情况下,Data中会有data。因此,如果您不想为此方法编写Objective-C包装器,则可能需要编写类似的内容:

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
        }
        //...
    }
}

(未经测试,您可能需要修复某些部分。)

在Objective-C中,您可以将(UIImage *item, NSError *error)的Objective-C块传递给completionHandler的{​​{1}}。在这种情况下,商品提供者会尝试将所有种类的图片数据转换为loadItemForTypeIdentifier:options:completionHandler:

NSItemProviderCompletionHandler

  

讨论

     

...

     

项目

     

要加载的项目。指定块时,请将此参数的类型设置为所需的特定数据类型。 ...项目提供程序尝试将数据强制转换为您指定的类。

因此,如果您不介意编写一些Objective-C包装器,您可以编写如下内容:

NSItemProvider + Swift.h:

UIImage

NSItemProvider + Swift.m:

@import UIKit;

typedef void (^NSItemProviderCompletionHandlerForImage)(UIImage *image, NSError *error);

@interface NSItemProvider(Swift)
- (void)loadImageForTypeIdentifier:(NSString *)typeIdentifier
                          options:(NSDictionary *)options
                completionHandler:(NSItemProviderCompletionHandlerForImage)completionHandler;
@end

{YourProject} -Bridging-Header.h:

#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

并使用Swift作为:

#import "NSItemProvider+Swift.h"

在我看来,Apple应提供 if attachment.hasItemConformingToTypeIdentifier(IMAGE_TYPE) { attachment.loadImage(forTypeIdentifier: IMAGE_TYPE, options: nil) { myImage, error in //... } } 这种类型安全的扩展,您可以使用Apple Bug Reporter撰写功能请求。

答案 1 :(得分:2)

示例中使用了一个新的API,canLoadObject和loadObject

if (itemProvider.canLoadObject(ofClass: UIImage.self)) {
            itemProvider.loadObject(ofClass: UIImage.self, completionHandler: {
                (data, error) in
                print("==== adding image \(image) as note, error=\(error)")
})

https://developer.apple.com/documentation/uikit/drag_and_drop/data_delivery_with_drag_and_drop