Drag&Dropなどを実装していると、外部のアプリケーションへ登録したオブジェクトを引き渡すことがあるため、UTIの登録が必要になります。これまではCoreServices
やMobileCoreServices
を利用していましたが、iOS14, macOS11.0以降は UniformTypeIdentifiersの利用が推奨されています。
UniformTypeIdentifiersの使い方
例えばiOSでのD&Dの実装では以下のように使います。
import UniformTypeIdentifiers
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let object = dataStore.object(at: indexPath)
let data = object.title.data(using: .utf8)
let itemProvider = NSItemProvider()
// ここ
itemProvider.registerDataRepresentation(forTypeIdentifier: UTType.plainText.identifier, visibility: .all) { (completion) in
completion(data, nil)
return nil
}
return [UIDragItem(itemProvider: itemProvider)]
}
以前は何を使っていた?
iOS13以前はCoreServices
やMobileCoreServices
などが使われていました。
例えば先ほどのコードをMobileCoreServices
を使って書いてみると以下のようになります。
import MobileCoreServices
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let object = dataStore.object(at: indexPath)
let data = object.title.data(using: .utf8)
let itemProvider = NSItemProvider()
// kUTTypePlainText as Stringとなっている
itemProvider.registerDataRepresentation(forTypeIdentifier: kUTTypePlainText as String, visibility: .all) { (completion) in
completion(data, nil)
return nil
}
return [UIDragItem(itemProvider: itemProvider)]
}
UniformTypeIdentifiers
になって変わったことは?
kUTTypePlainText
のような、以前のフレームワークで参照できたkUTTypeはCFString
で宣言されていました。
これに対してUniformTypeIdentifiers
フレームワークではUTTypeというstructが定義されており、その下にplainTextなどのシステム定義のUTTypeがたくさん定義されています。
私は昔のApple開発環境に詳しくないため変更理由の正確な推察が出来ませんが、なんとなく「レガシーな仕組みを刷新したかったのかな」と推測しています。お詳しい方いらっしゃたらコメントで教えていただけると助かります。
古いフレームワークでの値と等価なのか?
機能テストを少し書いてみました。このテストがパスしたため、等価と言えます。
import XCTest
import CoreServices
import UniformTypeIdentifiers
class UTIFunctionTests: XCTestCase {
func testPlainText() throws {
XCTAssertEqual(kUTTypePlainText as String, UTType.plainText.identifier)
}
}
どこに移行に関する情報が書いてあるのか?
フォーラム
フォーラムでAppleのデベロッパーが回答している投稿を見つけました。
Hi yetanotherme! This API has been marked API_TO_BE_DEPRECATED because we've introduced an Objective-C and Swift replacement API, the UniformTypeIdentifiers framework.
(Posted 10 months ago by Frameworks Engineer , UTI deprecated?, Developer Forums, https://developer.apple.com/forums/thread/651819, viewed: 2021/05/17)
上記の引用文で書かれているように、CoreServices
とMobileCoreServices
はAPI_TO_BE_DEPRECATED
としてマークされており、将来的に非推奨にされるようです。
WWDC
こちらのセッションの後半でUniformTypeIdentifiersフレームワークへの置き換えについて話があります。
まとめ
UTIに関して、AppleはiOS14とmacOS11以降で利用可能なUniformTypeIdentifiers
フレームワークを提供しました。古いフレームワークは将来的に非推奨になることが決まっているため、利用可能な場合は新しいフレームワークを使いましょう。