【Core data】追加・更新・削除・取得!わかりやすく解説【swift】

iOSアプリ開発

「Core Data」って何だ!?

「Core Data」とは、iPhone端末でデータ保存をする際に使用するデーターベース(= SQLiteという名前のデータベースだよ)のフレームワークのことだ!
とりあえず「Core Dateを使えば、いっぱいのデータをアプリに保存できるぞ」という認識程度でOK!

Core Dataを使うために必要なものは!?

Core Dataを使うためには、プロジェクトを新規作成する際に「Use Core data」という項目にチェックを入れておくこと。

もしチェックを入れ忘れたり、既存のプロジェクトにCore Dataを追加したい場合は「AppDelegate.swift」にCore Data関係のソースコードを追加しなければいけない。ちょっとめんどくさい。

追加方法は検索すればすぐにヒットするので割愛します。

まずはデータベースの設定からだ!

Core Dataで使うデータベースの設定は、「プロジェクト名.xcdatamodeld」というファイルから行います。「Use Core data」にチェックを入れていれば、自動的に生成されていると思う。

「プロジェクト名.xcdatamodeld」の中はこんな感じ!

ユニークキーはどうすんの?(自動で連番ふってくれる機能はあるの?)

ユニークキーには自動で連番を振りたいところ。しかしCore dataには自動で連番をふってくれる機能がない。というかそもそもユニークキーの概念すらない。

なので

let myid: String = NSUUID().uuidString

こんな感じでID用のキー(乱数)を自分で生成し、擬似的なユニークキーとする。

画像を保存したい

Core Dataに画像を保存したい場合、まずカラムタイプを「Binary Data」にする。

その後、右側ビューの最右アイコンにて「Allows External Strorage」にチェックを入れておく。このチェックを入れることで、画像の処理スピードが上がる。(参考:http://swift-studying.com/blog/swift/?p=1035)

Core Dataの操作(取得・追加・更新・削除)

Core Dataを操作したいクラスにて、下記を記入。

let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext: NSManagedObjectContext = appDelegate.persistentContainer.viewContext

あとは目的の操作にあわせて、下記から選んで記入。

【余談】
・managedObjectContext は名前が変わって「viewContext」になったようだ。
・かつては「NSManagedObject subclass」という機能で、NSManagedObject サブクラスとやらを生成する必要があったらしいが、今では自動で生成されるようになったようだ。裏で自動生成されるのでプロジェクトフォルダ内では確認することができないが、ちゃんと生成されている。逆に「NSManagedObject subclass」でサブクラスを生成してしまうと、クラス名がかぶることで怒られる羽目になる。

取得

取得したデータをカラム別に配列に格納するサンプル。
下記の例では「String型のカラム1」と「Integer型のカラム2」をそれぞれ別の配列に格納しています。

let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "エンティティ名")

do {
let myResults = try managedContext.fetch(fetchRequest)

var column1 : [NSString] = []
var column2 : [NSInteger] = []

for myData in myResults {
column1.append(myData.value(forKey: "カラム名1") as! NSString)
column2.append(myData.value(forKey: "カラム名2") as! NSInteger)
}

} catch let error as NSError {
print("\(error), \(error.userInfo)")
}

もしも取得したデータが「entity:Sample; id: ・・・・data: 」のような謎の表示が出てしまった場合は、下記の一文を追加すると正常に取得できるようになります。

fetchRequest.returnsObjectsAsFaults = false

returnsObjectsAsFaultsが何者かは僕にはよくわからない・・・。

追加

「セル追加ボタン」を押したら、「test」という値のセルが追加される場合。

@IBAction func createFolder(_ sender: Any) {

let entity = NSEntityDescription.entity(forEntityName: "エンティティ名", in: managedContext)!
let ent_name = NSManagedObject(entity: entity, insertInto: managedContext)

ent_name.setValue("test", forKeyPath: "カラム名1")
ent_name.setValue("test", forKeyPath: "カラム名2")

do {
try managedContext.save()
} catch let error as NSError {
print("\(error), \(error.userInfo)")
}

}

更新

条件に指定したセルを更新する場合。

let fetchRequest = NSFetchRequest<NSManagedObject>(entityName:"エンティティ名")
//条件指定
fetchRequest.predicate = NSPredicate(format: "カラム名 = %@", 値)

do {
let myResults = try managedContext.fetch(fetchRequest)

for myData in myResults {
myData.setValue("新しい値", forKeyPath: "カラム名")
}

try managedContext.save()
} catch let error as NSError {
print("\(error), \(error.userInfo)")
}

削除

条件に指定したセルを削除する場合。

let fetchRequest = NSFetchRequest<NSManagedObject>(entityName:"エンティティ名")
//条件指定
fetchRequest.predicate = NSPredicate(format: "カラム名 = %@", 値)

do {
let myResults = try managedContext.fetch(fetchRequest)
for myData in myResults {
managedContext.delete(myData)
}

try managedContext.save()
} catch let error as NSError {
print("\(error), \(error.userInfo)")
}

トラブル集

開発中おかしなデータが格納されてしまったのでデータベースをリセットしたい

シミュレーターから普通にアプリを削除して、ビルドしなおせばOK。


Category
9WEB