[Swift 4][OSS] struct、image、dataを簡単にファイルへ永続化できる?「Disk」を試してみた
? Diskとは
リポジトリから引用します。
Delightful framework for iOS to easily persist structs, images, and data
struct、image、dataを簡単に永続化するためのiOS用のフレームワークとのこと。
MITライセンスで公開されています。
今回はこのDiskを試してみました。
検証環境
本記事は以下の環境で検証を行っています。
- macOS Sierra バージョン 10.12.6
- Xcode Version 9.0 beta 6 (9M214v)
- Swift 4
- iPhone 7 Plus シミュレーター iOS 11.0
- CocoaPods 1.3.1
README.mdに以下の記載があります。
Disk uses the new Codable protocol introduced in Swift 4 to its utmost advantage and gives you the power to persist structs without ever having to worry about encoding/decoding.
Swift 4から使えるCodable
プロトコルを使っているということでXcode 9(記事執筆時点ではベータ版)を使う必要があります。
また、CompatibilityによるとiOS 9以上が必要とのことです。
本記事は ベータ版のXcode 9を使用して検証を行っています。そのため、正式版がリリースされた際にはライブラリの使用方法等が変わる可能性があります。ご留意の上、お読みください。
セットアップ方法
Carthageにも対応していますが、今回はCocoaPodsでインストールします。
Podfile
に以下を記載し、pod install
します。
target 'DiskSample' do use_frameworks! pod 'Disk' end
記事執筆時点でバージョン0.2.1
がインストールされました。インストール後は.xcworkspaceファイルを開けばDiskが使える状態になります。
使ってみる
Diskは記事執筆時点で以下のデータ型のファイルへの永続化をサポートしています。
特徴はなんといってもCodable
プロトコルをサポートしていることではないでしょうか!?
Codable
[Codable]
UIImage
[UIImage]
Data
[Data]
Codableを保存する
まずは以下のようにCodable
に準拠したstructを定義します。
struct User: Codable { let id: Int let name: String? }
このstructを保存してみます。
保存先はDocumentsディレクトリにしていますが、他にもcaches
とtemporary
が指定できます。
let user1 = User(id: 1, name: "Kato") let user2 = User(id: 2, name: nil) try? Disk.save(user1, to: .documents, as: "user1.json") try? Disk.save(user2, to: .documents, as: "user2.json")
実行してディレクトリを覗いてみるとちゃんとjsonファイルが保存されていました。
ファイルをテキストエディタで開くとこんな感じ。
user1.json
{"id":1,"name":"Kato"}
user2.json
{"id":2}
たった1行で保存できて便利ですね。
保存したCodableを読み込む
保存ができたので読み込んでみます。読み込むのも簡単です。
// User.selfを指定することで結果をUser型として受け取れる if let user1 = try? Disk.retrieve("user1.json", from: .documents, as: User.self) { print(user1) // User(id: 1, name: Optional("Kato")) } if let user2 = try? Disk.retrieve("user2.json", from: .documents, as: User.self) { print(user2) // User(id: 2, name: nil) }
保存時にサブディレクトリを作成する
保存時にディレクトリのパスを含むようにすれば自動でディレクトリを作成してくれます。 以下のように階層が深くても大丈夫。
// Documentsディレクトリにサブディレクトリを作成して保存する try? Disk.save(user1, to: .documents, as: "directory1/directory1_1/user1.json")
Data型を保存・読み込む
以下のようにしてData型を保存・読み込みます。
// 保存 let data = "データだよ".data(using: .utf8)! try? Disk.save(data, to: .documents, as: "data") // 読み込み if let retrievedData = try? Disk.retrieve("data", from: .documents, as: Data.self) { print(String(data: retrievedData, encoding: String.Encoding.utf8)!) // データだよ }
ちゃんと保存されてますね。
UIImageを保存・読み込む
以下のようにUIColorとCGSizeを指定してUIImageを生成する関数を用意しました。
/// UIColorとCGSizeを指定してUIImageを生成する。 /// /// - Parameters: /// - color: 色 /// - size: サイズ /// - Returns: UIImage func image(color: UIColor, size: CGSize) -> UIImage { let renderer = UIGraphicsImageRenderer(size: size) return renderer.image { ctx in ctx.cgContext.setFillColor(color.cgColor) ctx.fill(CGRect(origin: .zero, size: size)) } }
上記の関数を使用してUIImageの保存・読み込みを行ってみました。
// UIImageを生成 let myImage = image(color: .red, size: CGSize(width: 100, height: 100)) // 保存 try? Disk.save(myImage, to: .documents, as: "myImage") // 読み込み if let myImage = try? Disk.retrieve("myImage", from: .documents, as: UIImage.self) { print(myImage) // <UIImage: 0x6040000b6800>, {300, 300} }
おわりに
今回はstruct、image、dataを簡単にファイルに永続化できるDiskを試してみました。本当に簡単に使えますね!
なお、本記事ではサンプルなのでエラーハンドリングをtry?
やtry!
で済ませてしまっていますが必要に応じてちゃんとエラーをcatchしてエラー処理するようにしてください。