Reputation: 531
In the beginning of the project, Realm is great and easy to work and the project is getting complicated so I need to figure out how to decouple the realm layer and uiviewcontroller.
There is some awkwardness by writing a realm object with parameters. I would like to have object updated with the parameter then pass to the realm database to update object in (table?). Initially, I have a function to write a realm object by -
func createOrUpdateNote(note : Note, body : String, textSize : Float, toggleColor : Int) {
let realm = try! Realm()
do {
try realm.write {
if note.id == -1 {
note.id = NoteManager.createNotePrimaryId()
}
note.body = body
note.textSize = textSize
note.toggleColor = toggleColor
realm.add(note, update: true)
}
}
catch {
print(error.localizedDescription)
}
}
I would like to have like this function. Hope it clears up my question here.
func createOrUpdateNote(note : Note) {
let realm = try! Realm()
do {
try realm.write {
realm.add(note, update: true)
}
}
catch {
print(error.localizedDescription)
}
}
Now I have another viewcontroller to update the object with their preference of using language below.
func createOrUpdateNote(note : Note, language : String) {
let realm = try! Realm()
do {
try realm.write {
if note.id == -1 {
note.id = NoteManager.createNotePrimaryId()
}
note.language = language
realm.add(note, update: true)
}
}
catch {
print(error.localizedDescription)
}
}
There will be two similar functions (dup functions) in database layer and that will not work well when the project is getting more features so I'm stepping back to see if I can redesign the create or update the object approach.
I googled and there are several solutions like making UI object and copy the ui values over to the realm objects each time I do CRUD, create object with internal realm object (1 to 1 mapping), or I'm thinking about partial update but not sure how can I approach this situation. Ideally, I would prefer only object to carry over to be updated. Any suggestions?
Upvotes: 2
Views: 2932
Reputation: 35648
If you have an existing (managed) Realm object, its properties can only be modified within a write block. However, ANY of it's properties can be modified and you really only need one block 'style' to do it.
So for example, if we have a Note Realm object
Note: Object {
@objc dynamic var body = ""
@objc dynamic var textSize = 12
@objc dynamic var language = "English"
}
any time we have access to that Note, we can modify it's properties within a write closure. Let's say a user is editing an existing note and changes the body, then clicks Save.
let realm = try Realm()
try! realm.write {
myNote.body = updatedBodyText
realm.add(myNote, update: true)
}
or they change the text size
let realm = try Realm()
try! realm.write {
myNote.textSize = updatedTextSize
realm.add(myNote, update: true)
}
Notice that those blocks are identical, other than which property is updated. The key is to hang on to a reference to the note when loaded, so you can then modify it's properties in a write block when saving.
There's no problem having multiple write blocks depending on what property you're saving. It really depends on your use case but that's common practice.
Generically speaking it could also be rolled into one function, something like this:
func saveMyNote(myNote: NoteClass, updatedData: String, fieldType: NoteFieldTypes) {
try! realm.write {
switch fieldType:
case .body:
myNote.body = updatedData
case .language:
myNote.language = updatedData
etc etc
realm.add(myNote, update: true)
}
You could also extend the class or a variety of other solutions. In general the write code is so small I would just use it wherever you need to update an objects fields.
Upvotes: 1