<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">What is the current plan for persisting things like enums and structs in Swift?<div class=""><br class=""></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div 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.</div><div class=""><br class=""></div><div class="">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…</div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> horribleAutocastHack<T>(x:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Any</span>, fail:(()<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span>-> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>)? = <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">nil</span>)<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> cast = x <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">as</span>? <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> cast</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> fail = fail{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">try</span> fail()</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">fatalError</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span>"Autocast failed"<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">I was able to get the rest working though. </div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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...</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""></div></body></html>