What is the current plan for persisting things like enums and structs in Swift?


After the POP talk at WWDC, I excitedly rewrote many of my frameworks to use 
protocols and structs/enums instead of NSObject subclasses.  For the most part, 
this has been fantastic… most things are much more powerful/flexible using 
protocols and value types.  The one problem I keep running into, however, is 
how to persist things in the same way you can with NSCoding.  NSCoding requires 
NSObject as a base class.

I spent the last couple of weekends playing with ideas for a persistence 
framework and I was able to get about 90% of the way there.  I was able to 
encode types like [(Int,Float)] by supplying closures to the encoding function. 
 For example:  func encodeArray<T>(array:[T], forKey:String, 
mapping:(T)->Encoding).  There is a simpler version without the closure for 
arrays where T adheres to my “Encodable” protocol:  func 
encodeArray<T:Encodable>(array:[T], forKey:String).  I also have legacy support 
for objects which adhere to NSCoding.

Instead of going straight to data like NSCoding, I encode to an intermediate 
format (A struct with an internal enum).  Then you have another protocol which 
can turn that format into data, json, plist, etc…

90% working, but I ran into a few problems.  First, I have to use this horrible 
thing to get the type system to cooperate in some cases:

func horribleAutocastHack<T>(x:Any, fail:(()throws-> T)? = nil)throws -> T{
    if let cast = x as? T{
        return cast
    }
    if let fail = fail{
        return try fail()
    }
    fatalError("Autocast failed")
}


Second, I had to use static methods instead of init in my protocol, since init 
fails on classes where I don’t have access to the code (e.g. NSData).  It wants 
me to mark it both required and final, which I can’t do.

Third, I have no idea how to persist closures. It may just be flat out 
impossible.  The big effect it has had is that anywhere where I had to build a 
thunk to store a collection of heterogeneous objects (adhering to a protocol 
with self requirements) it can no longer be persisted.  This is actually the 
biggest issue, and I haven’t even been able to hack around it.

Finally, I am pushing the generics system pretty hard.  My first version was 
randomly crashing the compiler so I had to pull back on that front (e.g. having 
encodeArray instead of just encode which infers the arrayness).  All of the 
various discussions around factory methods are also relevant.

I was able to get the rest working though.  

Is there an official plan which I am duplicating effort on?  I would be happy 
to share my code (after a couple more iterations) if that would be 
helpful/inspiring.  I would also be happy to just work on other things and wait 
for the official solution if there is one coming…  I may have to wait for more 
powerful generics in any case.

I feel like this is one of those things that is impacting a lot of real world 
codebases, and delaying adoption of POP, value types, etc...

Thanks,
Jon

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to