Releases: RougeWare/Swift-SerializationTools
1.1 • `CodableBridge`
This adds CodableBridge
, which bridges the gap between NSCoding
and Codable
!
Codable
is the Swift re-imagining of NSCoding
. I think we all can agree that Codable
is much better!
But, some things (especially in Apple frameworks) conform to NSCoding
but not Codable
! What is one to do?
Well, never fear! A solution* is here!
// Probably the most common way that I run into this is with AppKit and UIKit, so let's use those as examples!
struct User: Codable, Equatable {
let name: String
let avatar: UIImage.CodableBridge?
let favoriteColor: UIColor.CodableBridge
}
// I'll only use one instance this time, because I think it's enough to get the point across.
// Here's Redd. He likes the color red!
//
// Here we see the concession to the API user: they have to use `.codable` to create the codable bridge.
// I recommend making a sugary initializer which just takes the base type, like
// `init(name: String, avatar: UIImage, favoriteColor: UIColor)`
let redd = User(
name: "Redd",
avatar: UIImage(named: "Redd-avatar").codable,
favoriteColor: UIColor(hue: 0.111, saturation: 0.78, brightness: 0.96, alpha: 1).codable
)
// And I'm sure you expect this, but that struct needs nothing more special to be able to encode &and decode it!
let reddJsonString = try redd.jsonString()
// Essentially {"name":"Redd","avatar":"<insert Base64 nonsense here>","favoriteColor":"<insert Base64 nonsense here>"}
let decodedRedd = try User(jsonString: reddJsonString)
// And of course the decoded value is just the same as before it was encoded, just like any native `Codable` type:
assert(decodedRedd == redd)
// The other caveat is that accessing the base type's methods is a bit indirect as well:
redd.favoriteColor.value.set()
// But at least accessing fields is straightforawrd thanks to `@dynamicMemberLookup`:
print(redd.avatar.size)
* Due to the limitations of Swift's approach to reference type initializers, a true
Codable
implementation can't be synthesized on allNSCoding
types without risking a crash for invalid data. As such, I've decided to make a synthesized subtype of allNSCoding
types, which can be as easily (en/de)coded. I tried to make this as ergonomic as possible; let me know if you have any better ideas!
Patch changes
1.1.1
- Added automatic conformance to
Equatable
andorHashable
if its base type conforms to them
1.0.0 - MVP
Kicking this off with a pattern I've used in bunches of projects in my past. This vastly simplifies (de)serializing to/from JSON.
This applies to all Codable
types! Just import SerializationTools
and you get this for free:
import SerializationTools
let deserialized = try MyStruct(jsonData: someData)
let serialized = try deserialized.jsonString()