[swift-users] dealing with heterogenous lists/dictionary with Codable

David Baraff davidbaraff at gmail.com
Thu Oct 19 12:15:09 CDT 2017


Begin forwarded message:

> From: Itai Ferber <iferber at apple.com>
> Subject: Re: [swift-users] dealing with heterogenous lists/dictionary with Codable
> Date: October 19, 2017 at 9:39:25 AM PDT
> To: David Baraff <davidbaraff at gmail.com>
> Cc: Geordie Jay <geojay at gmail.com>, swift-users <swift-users at swift.org>
> 
> Hi David and Geordie,
> 
> That approach won’t work — encoders and decoders only work directly with concrete Codable types (e.g. String, Int, MyFoo [where MyFoo is Codable], etc.).
> This is by design: since there is no type information stored in the JSON payload, there isn’t necessarily a way to tell how to decode the type you’re looking at, so asking for a generalCodable` isn’t helpful.
> 
> Since it’s unlikely that what you truly need is a [String : Any] but really a [String : <one of String, Int, MyFoo, etc.>], one easy way to decode this type is to create a wrapper enum or similar which overrides init(from:) to be able to decode from one of those types. You can then ask to decode a [String : MyWrapperType] and use that instead.
> 
> What types are you expecting in the dictionary?
> 
> 

The problem is that I want to be able to encode types T where
	(a) T is String, Int
	(b) lists of T
	(c ) dictionaries of type <String, T>

The problem is the recursive nature: yes, my types are simple (say only base types String and Int) but the “nesting” level may be quite deep (a list of list of dictionaries of <etc.).


Let’s turn this around:  in addition to the JSONEncoder, one can also use the PropertyListEncoder.  

Are we saying that something one could pull from a property list file (which is pretty much what i want: arbitrary deep nesting of basic types) is also not Codable?  So a PropertyListEncoder could not encode actual property lists?

I really do want a heterogenous container.  I think I am stuck.

> — Itai
> 
> On 19 Oct 2017, at 18:11, David Baraff via swift-users wrote:
> 
> I’ll try.  Is that cast smart enough to apply recursively? We shall see.
> 
> Sent from my iPad
> 
> On Oct 19, 2017, at 7:34 AM, Geordie Jay <geojay at gmail.com <mailto:geojay at gmail.com>> wrote:
> 
>> I mean can you do something along the lines of
>> 
>> let codableDict = stringAnyDict as? [String : Codable]
>> 
>> ?
>> 
>> I’m not at a computer to test it myself
>> 
>> 
>> 
>> 
>> David Baraff <davidbaraff at gmail.com <mailto:davidbaraff at gmail.com>> schrieb am Do. 19. Okt. 2017 um 15:45:
>> That’s exactly what I want.  The ironic part is that I got my dictionary by decoding a Json file.  If that’s where my dictionary came from, is there a simple way of coercing the Json serialization routines to give me back codables, rather than Anys?
>> 
>> 
>> Sent from my iPad
>> 
>> On Oct 19, 2017, at 3:38 AM, Geordie Jay <geojay at gmail.com <mailto:geojay at gmail.com>> wrote:
>> 
>>> 
>>> David Baraff via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> schrieb am Do. 19. Okt. 2017 um 03:47:
>>> So I have simple structs like this:
>>> 
>>>         struct Library: Codable {
>>>                 let domain: String
>>>                 let unit: String
>>>         }
>>> 
>>> and it’s super-simple to serialize.  Yay.
>>> 
>>> But:
>>> 
>>>         struct LibraryGroup : Codable {         // I wish...
>>>            let libraries: [Library]
>>>            let someDict: [String : Any]
>>>         }
>>> 
>>> I haven’t tried this, but is it possible to have a dictionary of [String : Codable] ? Because that’s exactly the type requirements you’re describing, no?
>>> 
>>> Geordie
>>> 
>>> 
>>> So what I’m looking for is something where if the values in someDict are themselves Codable, I can serialize things, and if they’re not, I can’t.  In my previous scheme, I was using NSKeyedArchiver to serialize everything, manualy, including someDict; in trying to switch to Codable I ran smack into the fact that Codable wants to know what all the types are, in advance.
>>> 
>>> Am I just stuck?  How do I get the best of both worlds, where the compiler can make use of the fact that it can see the data types of my structures, while still being able to serialize heterogenous data like is found in LibraryGroup?
>>> 
>>> Is my only alternative to write a custom coder for LibraryGroup?  Is there any hope I could teach Codable what to do with
>>>         [String: Any]
>>> 
>>> ?
>>> 
>>> 
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org <mailto:swift-users at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20171019/35883fff/attachment.html>


More information about the swift-users mailing list