LoginSignup
9
3

More than 1 year has passed since last update.

UTIを参照したい時はUniformTypeIdentifiersフレームワークを使おう

Last updated at Posted at 2021-05-17

Drag&Dropなどを実装していると、外部のアプリケーションへ登録したオブジェクトを引き渡すことがあるため、UTIの登録が必要になります。これまではCoreServicesMobileCoreServicesを利用していましたが、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以前はCoreServicesMobileCoreServicesなどが使われていました。

例えば先ほどのコードを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)

上記の引用文で書かれているように、CoreServicesMobileCoreServicesAPI_TO_BE_DEPRECATEDとしてマークされており、将来的に非推奨にされるようです。

WWDC

こちらのセッションの後半でUniformTypeIdentifiersフレームワークへの置き換えについて話があります。

まとめ

UTIに関して、AppleはiOS14とmacOS11以降で利用可能なUniformTypeIdentifiersフレームワークを提供しました。古いフレームワークは将来的に非推奨になることが決まっているため、利用可能な場合は新しいフレームワークを使いましょう。

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3