TLDR: Best strategy when you can't use KVO and stateful/mutable model objects?
(I'd tag this as a question, because I'm really just seeking advice here.)
Current setup: I have an app, written in Swift, which uses YapDatabase. My models are plain structs. The objects going in and out of the database are NSCoding compliant helper classes, which are created on-demand when reading and writing. These helpers are short lived and not passed around the app.
(In case it's relevant, the application in question is using @danthorpe 's delightful YapDatabaseExtensions to accomplish this.)
Now I am trying to add CloudKit sync to this app, learning as I go from the CloudKitTodo example.
The approach taken in CloudKitTodo with a smart superclass (MyDatabaseObject) won't work in this environment, so I'm trying to come up with a good alternative to MyDatabaseObject.
This is where I'm feeling a bit stuck, as I'm still pretty new to both YapDatabase and CloudKit.
In order to implement the record handler and merge blocks I need to answer questions about what changed in the object.
By using Swift structs I've opted out of KVO and type introspection. This is obviously a trade-off and I'm perfectly happy to diff two instances myself, field by field.
I think my question is:
What would be an elegant way to get access to both the original and modified value in the record handler block?
I believe the recordHandler is invoked too late for me to read the original from the database?
I could use my NSCoding helper to add a shadow copy to my struct. This would carry over unchanged when creating new, modified values and be available when saving. Conceptually something like this (ignore that recursive value types are illegal):
struct Person {
let name: String
let syncInfo: Person? // Not persisted. Only read when saving.
}
Or perhaps I could duplicate the data in the database. Either in a parallel collection or in the metadata. This would double my local storage cost, but my data is so small that it would be acceptable.
Maybe I could somehow compare against fields in the CKRecord? If no CKRecord is found it's a newly inserted object and all fields must be updated.
I apologize if this comes of as a bit rambling. I feel like I just barely know enough to phrase the question.
TLDR: Best strategy when you can't use KVO and stateful/mutable model objects?
(I'd tag this as a question, because I'm really just seeking advice here.)
Current setup: I have an app, written in Swift, which uses YapDatabase. My models are plain structs. The objects going in and out of the database are NSCoding compliant helper classes, which are created on-demand when reading and writing. These helpers are short lived and not passed around the app.
(In case it's relevant, the application in question is using @danthorpe 's delightful YapDatabaseExtensions to accomplish this.)
Now I am trying to add CloudKit sync to this app, learning as I go from the CloudKitTodo example.
The approach taken in CloudKitTodo with a smart superclass (MyDatabaseObject) won't work in this environment, so I'm trying to come up with a good alternative to MyDatabaseObject.
This is where I'm feeling a bit stuck, as I'm still pretty new to both YapDatabase and CloudKit.
In order to implement the record handler and merge blocks I need to answer questions about what changed in the object.
By using Swift structs I've opted out of KVO and type introspection. This is obviously a trade-off and I'm perfectly happy to diff two instances myself, field by field.
I think my question is:
What would be an elegant way to get access to both the original and modified value in the record handler block?
I believe the recordHandler is invoked too late for me to read the original from the database?
I could use my NSCoding helper to add a shadow copy to my struct. This would carry over unchanged when creating new, modified values and be available when saving. Conceptually something like this (ignore that recursive value types are illegal):
Or perhaps I could duplicate the data in the database. Either in a parallel collection or in the metadata. This would double my local storage cost, but my data is so small that it would be acceptable.
Maybe I could somehow compare against fields in the CKRecord? If no CKRecord is found it's a newly inserted object and all fields must be updated.
I apologize if this comes of as a bit rambling. I feel like I just barely know enough to phrase the question.