データの保存はiOSアプリの持つ主要な機能です。たとえば、ユーザーが指定した色などの環境設定を保存したり、ウェブサイトのトークンをアプリに保存したり、ToDoリストのアプリを作ってタスクを保存したりすることができます。データをシステムに保存する方法はいくつもあります。
目次
User Defaults
Core Data
Keychain
iCloud CloudKit
この記事では、上記の方法それぞれについて、サンプルコードを使って解説します。
User Defaults
主な用途
わずか2〜3行のコードで、String
, Int
, Bool
, やどんな Data
オブジェクトも保存・取り出しができます。
通常は、ユーザーがオンボーディングを終えたかどうかや、天気アプリでのユーザーのデフォルト都市等、ユーザーのプリファレンスを保存するのに使用されます。
長所
- わずか数行のコードで簡単に実装
- App Extensions 間でも簡単に共有
- クラウドにデータを保存でき、ユーザーの所有デバイス間で同期可能( 同じApple ID でサインイン)
短所
シンプルなデータの保存のみに使います。データベーススキームはありません。また Apple によると、UserDefaults
ストレージが512 KBに達すると警告が発せられます。そして Apple のドキュメンテーションには、ストレージが1MBに達するとアプリが終了するとあります。
Currently, there is only a size limit for data stored to local user defaults on tvOS, which posts a warning notification when user defaults storage reaches 512kB in size, and terminates apps when user defaults storage reaches 1MB in size.
https://developer.apple.com/documentation/foundation/userdefaults/1617187-sizelimitexceedednotification
しかし、Stack Overflow のユーザーの一人は、1MB以上のデータを保存してもクラッシュを起こしていないと報告しています。
ですから、ユーザーのプリファレンスや文字列・Int値をいくらか保存したい程度であれば心配することはありません。
使い方
//To store a value
UserDefaults.standard.set("Tokyo", forKey: "currentCity")
//To read a value
let currentCity = UserDefaults.standard.string(forKey: "currentCity")
(クラウド同期バージョン)の使い方
iCloudの機能を有効にする
プロジェクト設定の Signing & Capabilities
タブで、プラスボタンをクリックします。
そして、iCloud
機能を追加します
Key-value storage
をオンにします
そして、すべてのUserDefaults.standard
をNSUbiquitousKeyValueStore()
に置き換えるだけです:
let store = NSUbiquitousKeyValueStore()
store.set("Tokyo", forKey: "currentCity")
let currentCity = store.string(forKey: "currentCity")
資源
Core Data
主な用途
Core Data
には幅広い用途があります。私の個人的な開発では、Core Data
を使ってユーザーの日記、ToDoアイテム、ブックマークを保存しています。
Core Data
はユーザーの情報を既存の多くのアプリに保存するために広く使われています。
長所
- 構造化データの保存(データベーススキームを設計する必要があります)
- 数分以内にクラウド同期サポートを有効にできる
短所
- データベーススキームを変更するたびに、新しいデータベースバージョンを作成する必要があります。そうしないとアプリがクラッシュしてしまいます。
使い方
新しいアプリ
新しいアプリを作成する場合は、プロジェクトの作成時に Use Core Data
を選択できます。
既存のアプリ
また、既存のアプリに Core Data
を簡単に追加できます。
最初に、データモデルファイルを作成します。キーボードのcommand-Nキーを押して、Data Model
を検索します。
新しい Data Model
にあなたのアプリの名前をつけてください。例えば、ここでは私のアプリの名前は CoreDataDemo
なので、私は CoreDataDemo.xcdatamodeld
を作りました。
そして AppDelegate.swift
ファイルに次の行を追加します。
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "CoreDataDemo")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
print(error.userInfo)
}
})
return container
}()
この行で、 CoreDataDemo
をあなたのアプリの名前に置き換えてください。
let container = NSPersistentContainer(name: "CoreDataDemo")
データベース構造の作成
To-Doアイテムごとに次のプロパティを格納するTo-Doアプリを作成するとします:
- To-Doタスク名
- タスクの担当者
- タスクの期限
1. .xcdatamodeld
ファイルを開き、Add Entity
をクリックします。
作成した新規エンティティ・アイテムに TodoItem
という名前を付けます。
作成した新しいアイテムをダブルクリックし、名前を付けるだけです。この例では、 TodoItem
という名前を付けます。
新しいプロパティを追加する
Properties
セクションのプラスアイコンをクリックして、新しいプロパティを追加します。
ここでは、To-Doアプリに次のプロパティが必要です。
プロパティ名 | タイプ |
---|---|
todoTaskName | String |
personName | String |
taskDeadline | Date |
タイプを設定するには、プロパティ名の横にあるドロップダウンメニューをクリックします:
このような感じになります。
Entity クラスのコードファイルを生成
- 作成した新しいエンティティ項目を選択します。右側のパネルで最後のセクションのアイコンを選択します :
-
Codegen
設定をManual/ None
に変更
以前の設定:
新しい設定:
- クラス定義ファイルを生成
最上部のメニューで Editor
をクリックし、Create NSManagedObject subclass...
をクリックします
こうしたサブクラスを生成することで、TodoItem
を新規オブジェクトの作成に直接使用できるようになります。
ファイルナビゲーターに以下のファイルが表示されます :
新規レコードを作成
func addNewToDoItem(todoTaskName: String, personName: String, taskDeadline: Date) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newItem = TodoItem(context: context)
newItem.todoTaskName = todoTaskName
newItem.personName = personName
newItem.taskDeadline = taskDeadline
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
既存のレコードを取得
func getAllPlannerDays() -> [TodoItem] {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let savedPlaceFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "TodoItem")
do {
let result = try context.fetch(savedPlaceFetch)
if let convertedResult = result as? [TodoItem] {
return convertedResult
}
} catch {
return []
}
return []
}
変更
func modifyObject(_ object: TodoItem, newDeadline: Date) {
object.taskDeadline = newDeadline
//保存する
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
削除
func deleteObject(_ object: NSManagedObject) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
context.delete(object)
//保存する
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
プログラムから TodoItem
をご自身のエンティティ名に置き換えてください。
特定のレコードをクエリ中
すべての TodoItem
に対し personName
を ネコノヒー
としてクエリしましょう
func getToDoItem(withPerson: String) -> [TodoItem] {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let savedPlaceFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "TodoItem")
savedPlaceFetch.predicate = NSPredicate(format: "personName = %@", withPerson)
do {
let result = try context.fetch(savedPlaceFetch)
return result as? [TodoItem]
} catch {
return []
}
return []
}
let allTodo = getToDoItem(withPerson: "ネコノヒー")
ユーザーのコアデータをクラウドに同期する
すでにここにガイドを書いています:
新しいデータベースバージョンの作成
データベースの新しいバージョン(プロパティの追加、変更、削除、または新しいエンティティの作成)を作成するたびに、データベースの新しいバージョンを作成する必要があります。
データベースモデルファイルを選択した状態で、「Editor エディター」をクリックし、「Add Model Version モデルバージョンの追加」をクリックします。
次に、ファイルナビゲーターで、データベースモデルファイルの左側にある三角形のアイコンをクリックします。
作成した新しいデータモデルバージョンをクリックします。
右側のパネルでファイルアイコンをクリックし、「Model Version モデルバージョン」を見つけて、作成した新しいモデルバージョンに切り替えます。
左側のパネルで、作成したバージョンに緑のチェックマークが付いていることを確認してください。
資源
KeyChain (キーホルダー)
主な用途
ユーザーの機密情報を保存する場合は、Key Chainに保存することをお勧めします。Keychainは、iOSがユーザーのウェブサイトのユーザー名とパスワードを保存する場所です。暗号化されており、ユーザーのパスコードまたはFace ID (Touch ID)でのみアクセスできます。
長所
- セキュリティー
- 保存された認証情報は、ユーザーのデバイス間で同期できます。
短所:
- ユーザーはMac OS KeychainアプリでKeychainに保存したデータを見ることができます
- 通常、開発者はkeychainに文字列を保存します。データを保存することはお勧めしません。
使い方
keychainにアクセスするのに必要なコードはいくつかありますが、私はkeychainに簡単にアクセスできるオープンソースのGithubリポジトリを見つけました。
資源
CloudKit
長所
-
- データをプライベート・データベース、共有データベース、またはパブリック・データベース(すべてのユーザーが他のユーザーのレコードをフェッチできる)に保存できます。
- CloudKitはAppleの無料クラウドサービスです。
- CloudKitプライベート・データベースへの保存は、ユーザー自身のiCloudストレージスペースに対してカウントされます。
- CloudKitパブリック・データベースへの保存は、割り当て制限に対してカウントされます。
- ユーザーがアプリを削除してから再度インストールすると、CloudKitに保存されているデータをフェッチできます。
短所
- ユーザーはオンラインである必要があります。また、CloudKitデータベースの使用にはサイズ制限があります。
実装
私は以前、「CloudKit」を使用してユーザーの情報を保存および取得する方法についてのガイドを紹介しました: