Spine
Spine copied to clipboard
Change Resource class to protocol
Hi there! This is going to be a bigger issue. So I create some sections..
Prologue
I'm using Spine for an iOS application that syncs with JSON API endpoints. The Resource
objects by Spine
are converted to NSManagedObject
s and stored in the app for the offline mode. Since you can also edit these CoreData
objects, this leads to the classic client-server sync problem on the one side. On the other side you will always have the conversion from Resource
to NSManagedObject
and vice versa.
Proposal
I was wondering whether it would to practical to change Resource
from a class to a protocol. In this way you could extend a NSManagedObject
to be a Resource
using both CoreData
and Spine
functionality. This should not replace the current implementation of Resource
as a standalone object. By using protocol extension, you can provide default implementations of standalone objects, CoreData
, or other databases (like Realm.io). Yes, I have seen #17 but it is a year old.
The usage of a protocol would trigger more generic type throughout the code. Furthermore, Swift is static typed. I think it could be great if we could use to optimizations of the compiler and the latest swift 3 features. For example:
- More usage of generics (e.g.
ResourceCollection
,SaveOperation
,DeleteOperation
, ...) - Change
Field
to a protocol-enum combination (still thinking about this)
A Resource
protocol would also prevent code like:
open class var resourceType: ResourceType {
fatalError("Override resourceType in a subclass.")
}
This method implementation will be enforced by the protocol.
Current state
I already made some local changes. Some critical complication occur when adapting the code of Deserialization
(Relationships) and ResourceFactory
. But I think this will work.
Closing words @wvteijlingen What is your opinion on this? I'm aware that this would be quite a big change. But I can't and will not maintain a fork of Spine.
Hi Max!
Thanks for your extensive writeup. I fully agree with you, I'd love to have Resource
as a protocol. In fact, I've already tried numerous times to refactor it. The use case I had in mind is exactly what you described.
Unfortunately every time I ran into the type system that did not allow me to express what I wanted. I can't remember exactly what the issues were, but I think it was something with associated types and type constraints that didn't work with protocols.
Making more use of generics, such as generic collections, is also something I've tried to do before. What I ran into here is that you need to know beforehand what resource type will be returned from the server. To get this to work with included (sideloaded) resources proved to be a lot of work, and thus I've abandoned that for now.
That said, it might be worth it to look into this again and see if things changed with Swift 3. Would you be willing to work on this?
I can give it a try. But I can't make any promises. I think at some point I will have to ask for your counsel and/or help for realizing this.