[swift-evolution] [Review] SE-0166: Swift Archival & Serialization

Rex Fenley rex at remind101.com
Mon Apr 10 18:58:45 CDT 2017


How exactly does that work from the perspective of the initializer if you
have 2 sets of keys to choose from? Would I extend the initializer to
include my feature flag `public init(from decoder: Decoder, flag: Bool)
throws` and switch on that? Or could I pass in the Container I want to use
somehow, which seems cleaner to me as an abstraction? (This is similar to
what we're already doing with the setup we have.) How does a key jump
multiple levels "permissions.can_send_message" and is there a way to know
ahead of time which key maps to what property? Needing to express every
possible mapping from the initializer seems clumsy to me and I think would
fit better as a part of the Container itself.

On Mon, Apr 10, 2017 at 3:13 PM, Tony Parker <anthony.parker at apple.com>
wrote:

> Hi Rex,
>
> On Apr 10, 2017, at 12:48 PM, Rex Fenley via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Forgive me if I'm missing something, this is a very large proposal and a
> lot to parse through. I like how everything is designed as far as I can
> tell except I'm not sure from this proposal how one would compose multiple
> different types of Decoders against the same output type. For example, with
> Location we have.
>
> // Continuing examples from before; below is automatically generated by
> the compiler if no customization is needed.
> public struct Location : Codable {
> private enum CodingKeys : CodingKey {
>         case latitude
>         case longitude
>     }
>
>     public init(from decoder: Decoder) throws {
>         let container = try decoder.container(keyedBy: CodingKeys.self)
>         latitude = try container.decode(Double.self, forKey: .latitude)
>         longitude = try container.decode(Double.self, forKey: .longitude)
>     }
> }
>
> However, this initializer seems strictly tied to the `CodingKeys` set of
> coding keys. From what it appears, if this was used to decode from JSON the
> format would have to always be:
>
> {
> "latitude" : 20.0
> "longitude" : 20.0
> }
>
> I have a use case we're on my client we began the process of switching
> from one version of an API to another. In one version we had a payload
> similar to
>
> {
> "user" : {
> "uuid" : "uuid string..."
> "can_send_message" : true
> "can_delete_message" : false
> }
> }
>
> this would result in the following Codable (from "user") from what I'm
> following
>
> public struct User : Codable {
> private enum CodingKeys : CodingKey {
>         case uuid
>         case can_send_message
>         case can_delete_message
>     }
>
>     public init(from decoder: Decoder) throws {
>         let container = try decoder.container(keyedBy: CodingKeys.self)
>         uuid = try container.decode(Double.self, forKey: .uuid)
>         canSendMessage = try container.decode(Bool.self, forKey:
> .can_send_message)
>         canDeleteMessage = try container.decode(Bool.self, forKey:
> .can_delete_message)
>     }
> }
>
> when we began switching over to the new api the payload was returned as
>
> {
> user {
> "uuid" : "uuid string..."
> "permissions" : {
> "can_send_message" : true
> "can_delete_message" : false
> }
> }
> }
>
> Here with "permissions" we have a new internal container with a separate
> set of coding keys. Issue is in my use case I still need to maintain a way
> to decode the old version simultaneously; we guard all new changes behind
> feature flags in case something goes awry and we need to roll back our
> changes.
>
> How would one go about expressing this new Decoding and the previous
> Decoding simultaneously on the same User type?
>
>
> You would fall out of the automatically-generated scenario here, but this
> use case is exactly what the ‘container’ API is for. You can create a
> container with a new set of keys, then decode from it.
>
> Another approach would be to create a nested type that conforms with
> Codable which represents the “permissions” as a type of its own.
>
> - Tony
>
>
>
> --
> Rex Fenley  |  IOS DEVELOPER
>
> Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>  |
>  FOLLOW US <https://twitter.com/remindhq>  |  LIKE US
> <https://www.facebook.com/remindhq>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
 |  FOLLOW
US <https://twitter.com/remindhq>  |  LIKE US
<https://www.facebook.com/remindhq>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170410/49bcd27c/attachment.html>


More information about the swift-evolution mailing list