web-dev-qa-db-ja.com

Share Extension(Swift)でNSItemProviderデータ型を処理する

Share ExtensionプログラミングでSwift(3)に問題があります。
私の主な問題は、NSItemProviderdataタイプの処理にあります。
ここに問題があります:拡張機能を起動するアプリに応じて、異なるタイプのデータを取得します。例えば:
アプリケーションに次のように伝えます。

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

(注:attachmentはタイプNSItemProvider

フォトアプリから実行する場合、dataはURLなので、そこからUIImageを作成し、続行します。
問題は、一部のアプリケーションではdataがすでにUIImageであり、大文字と小文字を区別する方法が見つからないことです。
おそらくdataオブジェクトのデータ型をチェックするのが最善でしょうが、少なくとも私にとっては簡単なことではありません。
助けてくれてありがとう!

12
unixb0y

私がテストした限りでは、場合によっては、Datadataがあります。したがって、このメソッドの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)loadItemForTypeIdentifier:options:completionHandler:completionHandlerに渡すObjective-Cブロックを渡すことができます。このような場合、アイテムプロバイダーはすべての種類の画像データを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}-ブリッジング-Header.h:

#import "NSItemProvider+Swift.h"

そして、Swift as:

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

私の意見では、AppleはNSItemProviderのこの種のタイプセーフな拡張機能を提供するはずです。Appleの Bug Reporter を使用して機能リクエストを書くことができます。

15
OOPer

例で使用されている新しい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

1
Phuah Yee Keat