Foundationの最新情報 – WWDC2019

Session概要

Foundationフレームワークは、macOS、iOS、watchOS、tvOS SDKの全体で使用されるアプリやフレームワークのためのベースとなる機能を提供します。
このセッションでは、Foundationのコレクション、パフォーマンス、国際化機能とSwiftとの統合に対する有益なエンハンスメントについて取り上げます。

Foundationの新機能

Ordered Collection Diffing

  • コレクション間の差分を埋めることができるAPI
    • 下記の画像の例だと、BEAR から BIRD にリストの中身を変換したいとする。その際に”E”、”A”を削除して、”I”、”D”を插入すれば実現可能ということがわかりますが、Ordered Collection Diffingでは下記コードで上記を行っています。
  • String以外の型にも使える非常に有効なAPI

let diff = bird.difference(from: bear)
let newBird = bear.applying(diff) // [b, i, r, d]

Data

  • メモリの連続領域への割り当てを保証する
  • ContiguousBytes プロトコルを用いて実現
    • このプロトコルがあれば、未使用の領域にも直接連続した形で割り当てられます
  • DataProtocol
    • 様々なバッファタイプに適用するバイトの集まりである
  • MutableDataProtocol
    • DataProtocolの可変性を提供する

データの圧縮

Units(単位)

  • Foundationでは長さや速度などの一般的な単位をサポートしている
  • UnitDuration
    • ピコ秒まで対応可能になった
  • UnitFrequency(ヘルツを扱う)
    • framePerSecondプロパティを追加
      • フレームレート計算を行うのに理想的
  • UnitInformationStorage
    • デジタル情報の表示に使用する
    • 単位はビット、バイト、ニブル(nibbles)
    • キロ、キビ、ヨタ、ヨビなどもサポート
  • Relative Date Time Formatter
    • 現時点から見た日時を地域ごとに適した状態で表示可能
    • 返ってくる文字列はローカライズされており、様々なスタイルで活用可能
  • List Formatterが追加
    • リストの中身をローカライズされた状態かつ、言語に適した表示が可能
    • ListFormatter.itemFormatterを使用して文字列のローカライズが可能

let formatter = RelativeDateTimeFormatter()
let dateString = formatter.localizedString(for: aDate, relativeTo: now)

// en_US: "2 weeks ago"
// zh_TW: "2 週前"
let listFormatter = ListFormatter()
let dateFormatter = DateFormatter()

dateFormatter.dateStyle = .medium
listFormatter.itemFormatter = dateFormatter
let string = listFormatter.string(from: dates)

// en_US: "Aug 15, 2019, Sep 13, 2019, and Feb 1, 2020"
// es_ES: "15 ago 2019, 13 sept 2019 y 1 feb 2020

Operation Queue

  • Operation Queueを用いて、全てのタスク完了後に何らかの処理を行いたいとする(ここでは save())この処理を行う場合に新たなタスクを実行し、影響を与える可能姓があるため、妥当とはいえません
  • そのため、OperationQueue.addBarrierBlockを用いてタスク完了後の処理であることを担保します
  • ProgressReportingの追加
    • 実行中のジョブの進行状況を確認して表示したい時に totalUnitCountを使用すれば OperationQueue の進行状況を把握できます
    • OperationQueueに追加したタスクが1つ終了すると全体の進歩も一つ進みます

let queue = OperationQueue()
queue.progress.totalUnitCount = 3
queue.addOperation {
 task1()
}
queue.addOperation {
 task2()
}
queue.addOperation {
 task3()
}

ファイルシステム

  • iOSはUSBとSMBをサポート
  • 複数のボリューム上のファイル操作が可能になります
    • FileManager.itemReplacementDirectoryを使用する
    • ファイルの書き込み場所を選ぶ時やAtomic Safe-Saveを使う時
  • ボリュームの消失
    • USBを取り外したり、SMBサーバの接続が途切れると危険です
    • メモリMappedファイルを選ぶ時は mappedIfSafe を使用することで、ファイルを仮想メモリにマッピングできます
    • ただし、固定したボリュームだけが対象
  • USBやSMBサーバへのアクセスは遅いと感じた時の対処方法
    • アクセスをメインスレッドに集中させる
    • ファイルシステムの性能も確認する
  • 詳細は What’s New in File Management and Quick Look を参照

Swiftの更新

  • Scannerが1ラインで記述できるようになった
  • FileHandlerはファイル記述子にエラーが発生した差異に例外を投げるようになった
  • DataProtocolにより断片的なデータ処理が可能
// Swift 4
var nameNSString: NSString?
if scanner.scanUpToCharacters(from: .newlines, into: &nameNSString) {
 let name = nameNSString! as String
}
// Swift 5.1
let nameString = scanner.scanUpToCharacters(from: .newlines)
let matchedString = scanner.scanString(string: "hi, $")
// Error-based API
let fileHandle = FileHandle()
let data = try fileHandle.readToEnd()

// Works with DataProtocol
extension FileHandle {
 public func write<T: DataProtocol>(contentsOf data: T) throws
}
最新情報をチェックしよう!