主に一番最後の事例でハマったのでメモ。
前提
Realm 0.92.2を使用
import RealmSwift
class Todo: Object {
dynamic var id = NSUUID().UUIDString
dynamic var text = ""
dynamic var position = 1
dynamic var createdAt = NSDate()
dynamic var updatedAt = NSDate()
override static func primaryKey() -> String? {
return "id"
}
}
該当レコードを一括更新する
let realm = Realm()
var todos = realm.objects(Todo).filter("position BETWEEN %@", [1, 3])
realm.write {
todos.setValue(NSDate(), forKey: "updatedAt")
}
v0.91.2で追加されたsetValue
を使って更新する。
該当レコードを1つずつ更新する
filterの値以外を更新する場合
let realm = Realm()
var todos = realm.objects(Todo).filter("position BETWEEN %@", [1, 3])
realm.write {
for todo in todos {
todo.name += "hogehoge"
todo.updatedAt = NSDate()
}
}
for inで回して更新する。
filterの値を更新する場合
let realm = Realm()
var todos = realm.objects(Todo).filter("position BETWEEN %@", [1, 3])
realm.write {
var ids: [String] = []
for todo in todos {
ids.append(todo.id)
}
for id in ids {
if var todo = realm.objectForPrimaryKey(Todo.self, key: id) {
todo.position++
todo.updatedAt = NSDate()
}
}
}
Resultsをそのままfor inで回して更新する方法では、Results自体が更新されてしまって上手く処理出来ない。
一旦該当レコードのprimaryKeyを取得してから、改めて更新処理を実行すると上手くいく。
若干コードの見通しが悪いので、もし以外で良い方法があれば教えてください。