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
が返るので独自にメソッドを作ったほうが型セーフになっていいかもしれません。