目次
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の可変性を提供する
データの圧縮
- Compression framework
- データを圧縮するためのAPI
- 4つの圧縮方法をサポート
- lzfse
- lz4
- lzma
- zlib
Units(単位)
- Foundationでは長さや速度などの一般的な単位をサポートしている
- UnitDuration
- ピコ秒まで対応可能になった
- UnitFrequency(ヘルツを扱う)
- framePerSecondプロパティを追加
- フレームレート計算を行うのに理想的
- 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
}