NSItemProvider
概要
iOS/iPadOS では、ドラッグ&ドロップによってアプリ間でデータを移動させたり、あるアプリから Share Extension 等の App Extension にデータを共有したりできる。このような プロセス間のデータ移動 時に、移動対象のデータをラップするオブジェクトが NSItemProvider である。
NSItemProvider - Apple Developer
App Extension における NSItemProvider
Share Extension 等の App Extension では、他アプリから受け取るデータが NSItemProvider として取得できる。取得したデータに対して hasItemConformingToTypeIdentifier(_:) を利用すると、データの種別を UTI で判定できる。データ種別を判定できたら、その種別で loadItem(forTypeIdentifier:options:completionHandler:) を呼び出して、データをロードする。例えば、下記のような流れになる (NSExtensionItem 等については App Extension 参照)。
(ロードできるデータの判別は canLoadObject(ofClass:) でもできるようだった)
code:swift
import MobileCoreServices
class MyViewController: UIViewController {
func checkItem() {
guard let item = self.extensionContext?.inputItems.first as? NSExtensionItem else {
fatalError()
}
guard let attachment = item.attachments?.first else {
fatalError()
}
if attachment.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
attachment.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil) { item, _ in
guard let url = item as? URL else { return }
// 何か処理
}
}
if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
attachment.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil) { data, _ in
switch data {
case let image as UIImage:
// 何か処理
case let data as Data:
// 何か処理
default:
// 何か処理
}
}
}
}
}
NSItemProvider の初期化
NSItemProviderWriting を利用した初期化
init(object:) を利用して NSItemProviderWriting を与えて初期化できる。NSItemProviderWriting では、
サポートするデータ種別 (UTI)
対応する UTI によるデータのロード方法
などを定義できる。
code:swift
class MyModel: NSObject {
var name: String
var thumbnail: UIImage?
}
extension MyModel: NSItemProviderWriting {
// MARK: - NSItemProviderWriting
static var writableTypeIdentifiersForItemProvider: String = [
kUTTypeVCard as String,
kUTTypeUTF8PlainText as String
]
func loadData(withTypeIdentifier typeIdentifier: String,
forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Void) -> Progress? {
if typeIdentifier == kUTTypeVCard as String {
completionHandler(createVCard(), nil)
} else if typeIdentifier == kUTTypeUTF8PlainText as String {
completionHandler(name.data(using: .utf8), nil)
} else {
completionHandler(nil, ContactCardError.invalidTypeIdentifier)
}
return nil
}
}
NSItemProviderWriting - Apple Developer
プレビュー画像
previewImageHandler でプレビュー画像を設定できる (Optional)
複数フォーマットのサポート
registerItem(forTypeIdentifier:loadHandler:) で複数フォーマットでのデータのロードに対応できる