LoginSignup
7
6

More than 5 years have passed since last update.

CoreDataで自作クラスのAttributeを保存する方法

Last updated at Posted at 2018-09-13

概要

CoreData noobということもあって、AttributeのTypeに標準で用意されていない型をTransformableを使用して保存したい時に戸惑ってしまったので、備忘録として残しておきます。

恐らく、正解の流れとしては

  1. 保存したい自作クラスを定義
  2. そのクラスをNSCodingプロトコルに準拠させる
  3. エンコード処理とデコード処理の実装
  4. EntityのTypeをTransformableに設定する

です。以下で詳しく述べます。
Swiftのバージョンは4.1です。

自作クラスの定義

User.swift
class User: NSManagedObject {
  @NSManaged var name: String
  @NSManaged var pet: Pet
}

class Pet {
  var name: String?
  var gender: Gender?
}

enum Gender: Int {
  case male = 0
  case female
}

上記は、今回扱うデータモデルです。Userは名前と飼っているペットを持ち、Petは名前と性別を持っていることにします。UserクラスをCoreDataのEntityとして扱う為、NSManagedObjectを継承させ、プロパティには@NSManagedを付けています。

この記事のゴールは、petプロパティをAttributeとして保存できるようにすることです。

さて、上記のコードをそのまま書くと、「petプロパティは@NSManagedを使えんぞ!」と怒られてしまいます。どうやら、Obj-Cで表現できるクラスでなければならないようです。ですので、PetクラスにNSObjectを継承させます。

User.swift
...

class Pet: NSObject {
  var name: String?
  var gender: Gender?
}

...

これで怒られなくなりますが、まだCoreDataで扱える形にはなっていません。

NSCodingに準拠させる

続いて、PetクラスをNSCodingに準拠させ、エンコード処理とデコード処理を実装します。

User.swift
...

class Pet: NSObject, NSCoding {
  var name: String?
  var gender: Gender?

  func encode(with aCoder: NSCoder) {
    aCoder.encode(self.name, forKey: "Name")
    aCoder.encode(self.gender!.rawValue, forKey: "Gender")
  }

  required init?(coder aDecoder: NSCoder) {
    super.init()

    self.name = aDecoder.decodeObject(forKey: "Name") as? String
    let genderValue = aDecoder.decodeInteger(forKey: "Gender")
    self.gender = Gender(rawValue: genderValue)
  }
}

...

これでPetクラスをCoreDataで扱えるようになりました!

ここで注意すべき(僕が躓いた)ところは、enumもそのまま保存できるわけではないので、一旦rawValueを介してエンコード/デコードする必要があるところです。当然といえば当然なのですが...

Transformableに設定

最後に、AttributeのTypeをTransformableに変更して完了です。
スクリーンショット 2018-09-13 13.07.34.png

どうでもいいですけど、"AttributeのTypeをTransformableにする"って文章ヤバイですね。ヤバイ...(語彙力0)

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6