【问题标题】:Handle NSItemProvider data types in Share Extension (Swift)在 Share Extension (Swift) 中处理 NSItemProvider 数据类型
【发布时间】:2017-03-04 01:19:19
【问题描述】:

我对 Swift 中的 Share Extension 编程有疑问 (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 对象的数据类型,但至少对我来说这不是微不足道的。
提前感谢您的帮助!

【问题讨论】:

    标签: ios swift uiimage nsdata


    【解决方案1】:

    据我测试,在某些情况下,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 块传递给 loadItemForTypeIdentifier:options:completionHandler: 的 completionHandler。在这种情况下,项目提供者会尝试将各种图像数据转换为UIImage。

    NSItemProviderCompletionHandler

    讨论

    ...

    项目

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

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

    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"
    

    并在 Swift 中将其用作:

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

    在我看来,Apple 应该提供这种类型安全的 NSItemProvider 扩展,您可以使用 Apple 的 Bug Reporter 编写功能请求。

    【讨论】:

    • 非常感谢,太完美了!
    • 尝试了其他所有方法,这是有效的。
    【解决方案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

    【讨论】:

      猜你喜欢
      • 2019-04-22
      • 2019-11-11
      • 2021-12-29
      • 2015-08-04
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-16
      相关资源
      最近更新 更多