状態を永続化する
アプリケーションの再起動後もとの状態に戻せるようにすることを永続化とかいいます。
何を保存するか
今回は画像を再び表示させるようにしたいわけですが、保存すべき物を選択する余地が残されています。
元の状態に戻すために必要なものは
0. 画像自身
0. 画像のURL
0. 画像のAlias
のいづれかとなります。
いづれかを選びましょう。
どこに保存するか
一般的にはこのような場合は UserDefault を利用します。
ただし、画像のような大きなサイズのものはApplication Supportsディレクトリに保存するようにします。
UserDefaults
UserDefaultsはアプリケーションに必要な情報を保存するためにアプリケーションごとに用意された領域です。
ウインドウの位置やサイズ、テーブルビューの状態などを保存します。
辞書形式の領域なので取り扱いは簡単です。
取り出し(URLの場合)
swift
1let lastImageURLKey = "lastImageURLKey"
2
3// 保存されていなければnilが返る
4if let lastImageURL = UserDefaults.shared.url(forKey: lastImageURLKey) {
5
6 // 画像を読み込み
7}
保存(URLの場合)
swift
1let lastImageURLKey = "lastImageURLKey"
2
3UserDefaults.shared.set(imageURL, forKey: lastImageURLKey)
Application Supportsディレクトリ
慣習的にアプリケーションがその機能のために自由に使っていいとされてるディレクトリです。
保存場所の作成
Application Supportsディレクトリ内に自アプリケーション用のディレクトリを作成する必要があります。
swift
1private func supportDirName() -> String {
2
3 let main = Bundle.main
4
5 return main.bundleIdentifier
6 ?? main.infoDictionary?["CFBundleName"] as? String
7 ?? main.infoDictionary?["CFBundleExecutable"] as? String
8 ?? "UnknownAppliation"
9}
10
11private func searchedURL(for directory: FileManager.SearchPathDirectory) -> URL {
12
13 return FileManager.default.urls(for: directory, in: .userDomainMask)
14 .last
15 ?? URL(fileURLWithPath: NSHomeDirectory())
16}
17
18private func createDirectory(_ url: URL) -> Bool {
19
20 do {
21
22 try FileManager.default.createDirectory(at: url,
23 withIntermediateDirectories: false,
24 attributes: nil)
25
26 return true
27
28 } catch {
29
30 return false
31 }
32}
33
34private func checkDirectory(_ url: URL, create: Bool) -> Bool {
35
36 do {
37
38 let resourceValue = try url.resourceValues(forKeys: [.isDirectoryKey])
39 if !resourceValue.isDirectory! {
40
41 print("Expected a folder to store application data, found a file (url.path).")
42
43 return false
44 }
45
46 return true
47
48 } catch let error as NSError {
49
50 if create, error.code == NSFileReadNoSuchFileError {
51
52 return createDirectory(url)
53 }
54
55 return false
56 }
57}
58
59let supportURL = {
60 let url = searchedURL(for: .applicationSupportDirectory)
61 .appendingPathComponent(supportDirName())
62 guard checkDirectory(url, create: true) else {
63 return FileManager.default.temporaryDirectory
64 }
65 return url
66}()
67
取り出し
swift
1let storedLastImageName = "StoredLastImage.jpg"
2
3let storedLastImageURL = supportURL.appendingPathComponent(storedLastImageName)
4
5let image = NSImage(contentsOf: storedLastImageURL)
保存
swift
1let storedLastImageName = "StoredLastImage.jpg"
2
3let storedLastImageURL = supportURL.appendingPathComponent(storedLastImageName)
4
5let originalURL // オリジナルのURL
6
7try? FileManager.default.removeItem(at: storedLastImageURL)
8try? FileManager.default.copyItem(at: originalURL, to: storedLastImageURL)