12
9

More than 5 years have passed since last update.

RealmのObjectを簡単にコピーする方法

Last updated at Posted at 2016-05-07

ReaalmのObject(RLMObject)をコピーするのに手こずったのでまとめました。コピーすればスタンドアロンに戻るのでプロパティを操作できます。

方法は簡単でNSCopyingのプロトコルに対応するだけです。copyWithZone内でObjectを作成しそれを返します。String, BoolはStructなのでそのまま代入すればOKです。NSDateはclassなので参照を外すためにcopy()メソッドを使います。Listで配列を作っている場合は中身を取り出して再度Listを作ります。

RLMObject
class CategoryWrapper:Object{
    dynamic var category:String = ""
}

class HogeObject:Object, NSCopying {
    dynamic var entryID:String = ""
    dynamic var title:String = ""
    dynamic var updated:NSDate? = nil
    dynamic var content:String = ""
    let categories = List<CategoryWrapper>()
    dynamic var isDrafts:Bool = false

    override static func primaryKey()-> String? {
        return "entryID"
    }

    func copyWithZone(zone: NSZone) -> AnyObject {
        let copy = HogeObject()
        copy.entryID = entryID 
        copy.title = title
        copy.updated = updated?.copy() as? NSDate
        copy.content = content
        let categoriesRow = categories.map{ $0.category }
        let categoryWrappers = categoriesRow.map{
            category -> CategoryWrapper in
            let wrapper = CategoryWrapper()
            wrapper.category = category
            return wrapper
        }
        categoryWrappers.forEach{ copy.categories.append($0) }
        copy.isDrafts = isDrafts

        return copy
    }

}

取り出す際はcopy()を使います。

Copy

realm.write{
    realm.add(object, update: true)
    //standalone == false
}

object.title = "hoge" //standloneなので例外発生

let copy = object.copy as! HogeObject

copy.title = "hoge" //standaloneなのでプロパティを変更できる。

補足

copy()だとAnyObjectが返るので独自にメソッドを作ったほうが型セーフになっていいかもしれません。

12
9
1

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
12
9