Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-07-03 Thread Itai Ferber via swift-users

Hi Kevin,

You’re right — this is one of the limitations of the box design 
here. One thing we can do is expose the underlying boxed value as a 
`KeyedDecodingContainerProtocol` existential value using an accessor on 
the box so you can down-cast.


However, it shouldn’t be necessary to add any methods to 
`_JSONEncoder` or `_JSONDecoder` to support this. What are you trying to 
do?


— Itai

On 1 Jul 2017, at 9:07, Kevin Wooten wrote:


Itai,

I tried copying JSONEncoder.swift from the swift repo and implementing 
the `Unevaluated` type in it.  It doesn’t appear to be a workable 
solution due to the fact that the `KeyedEncodingContainer` type 
erasure box is the only value returned from `container(keyedBy:)`. 
This means that any extra methods implemented inside `JSONDecoder` (or 
`_JSONDecoder` in this case) can ever be publicly accessed (even with 
casting) unless the type erasure box also includes an equivalent 
method.


How do you propose getting around this?  Seems like the design of this 
might be a bit limiting when considering extension/enhancement in user 
specific code.




On Jun 29, 2017, at 12:47 PM, Itai Ferber  wrote:

Hi Kevin,

On Jun 29, 2017, at 12:30 PM, Kevin Wooten via swift-users 
> wrote:



Hi Jon,

I just joined this mailing list and have tried to catch up on the
history of this thread, so please excuse me if I’ve missed 
something.


I’m sorry the Codable API at the moment does not answer your 
needs —
you’re clearly not the only one who’s run into this, so let’s 
see

how we can work together to make the API better for everyone.
For one thing, in the case of grabbing a subtree of JSON as
"unevaluated" or "unmapped" (as it appears to be in the metadata 
case),
it should be fairly simple to add a `JSONDecoder.UnevaluatedJSON` 
type
that will allow you to essentially decode that part of the tree as 
an
`Any`. `JSONDecoder` would have knowledge of this type and would be 
able

to return the subtree inside of it — you’d decode a property as
`JSONDecoder.UnevaluatedJSON.self` and access the contents through 
`var
value: Any?`, or something similar. This would be simple additive 
API,
which although might not make it in the upcoming betas, should be 
fairly

simple introduce. Would this solve that use case?

We’re also working on improving `NSISO8601DateFormatter`. I 
don’t
think I saw it in any of your emails — what specific use case are 
you

looking for that it doesn’t at the moment support?

— Itai



Itai,

Is this a formal solution that is going to be implemented? This 
would solve just about every issue I currently have with Decodable.
I can’t make any promises at the moment — we’ve got a lot of 
high-priority things to fix before the Swift 4.0 release. However, 
this is something I’d certainly like to put through API review and 
eventually release, since this is clearly something that would be 
beneficial to a lot of our users.



Two points…

1) Putting it on `JSONDecoder` seems dubious since you’d only have 
access to `Decoder` (although conditional casting could solve that). 
It seems adding the method to `Decoder` and using 
`Decoder.Unevaluated.self` as the requested type, would be more 
useful. A user could then conditionally cast that value to things 
like `[String: Any]` and possibly use its contents generically.
Putting that on Decoder would require all Decoders to have an 
"unevaluated type" representation, which may not be appropriate for 
all formats.
Since this is very often a request when working with 3rd-party APIs 
which you don’t control (and are rarely offered in more than one 
format, if that), putting this directly on JSONDecoder seems 
reasonable — you’d only really expect this representation if 
you’re decoding from JSON; if you’re encoding to/from a different 
format, you’re likely in control of the data in those formats.


2) Matching it with an equivalent on `Encoder` would be great as 
well.  We take in JSON that has “metaData” like one 
aforementioned exampled. We then have to send back the equivalent 
metadata during a subsequent update; without ever inspecting or 
altering the unevaluated data. Being able encode a 
`Decoder.Unevaluated` would solve that problem as well.

Yes, we’d add an equivalent type on encode as well.




___
swift-users mailing list
swift-users@swift.org 
https://lists.swift.org/mailman/listinfo/swift-users





___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-07-01 Thread Kevin Wooten via swift-users
Itai,

I tried copying JSONEncoder.swift from the swift repo and implementing the 
`Unevaluated` type in it.  It doesn’t appear to be a workable solution due to 
the fact that the `KeyedEncodingContainer` type erasure box is the only value 
returned from `container(keyedBy:)`. This means that any extra methods 
implemented inside `JSONDecoder` (or `_JSONDecoder` in this case) can ever be 
publicly accessed (even with casting) unless the type erasure box also includes 
an equivalent method.

How do you propose getting around this?  Seems like the design of this might be 
a bit limiting when considering extension/enhancement in user specific code.


> On Jun 29, 2017, at 12:47 PM, Itai Ferber  wrote:
> 
> Hi Kevin,
> 
>> On Jun 29, 2017, at 12:30 PM, Kevin Wooten via swift-users 
>> > wrote:
>> 
>>> Hi Jon,
>>> 
>>> I just joined this mailing list and have tried to catch up on the 
>>> history of this thread, so please excuse me if I’ve missed something.
>>> 
>>> I’m sorry the Codable API at the moment does not answer your needs — 
>>> you’re clearly not the only one who’s run into this, so let’s see 
>>> how we can work together to make the API better for everyone.
>>> For one thing, in the case of grabbing a subtree of JSON as 
>>> "unevaluated" or "unmapped" (as it appears to be in the metadata case), 
>>> it should be fairly simple to add a `JSONDecoder.UnevaluatedJSON` type 
>>> that will allow you to essentially decode that part of the tree as an 
>>> `Any`. `JSONDecoder` would have knowledge of this type and would be able 
>>> to return the subtree inside of it — you’d decode a property as 
>>> `JSONDecoder.UnevaluatedJSON.self` and access the contents through `var 
>>> value: Any?`, or something similar. This would be simple additive API, 
>>> which although might not make it in the upcoming betas, should be fairly 
>>> simple introduce. Would this solve that use case?
>>> 
>>> We’re also working on improving `NSISO8601DateFormatter`. I don’t 
>>> think I saw it in any of your emails — what specific use case are you 
>>> looking for that it doesn’t at the moment support?
>>> 
>>> — Itai
>> 
>> 
>> Itai, 
>> 
>> Is this a formal solution that is going to be implemented? This would solve 
>> just about every issue I currently have with Decodable.
> I can’t make any promises at the moment — we’ve got a lot of high-priority 
> things to fix before the Swift 4.0 release. However, this is something I’d 
> certainly like to put through API review and eventually release, since this 
> is clearly something that would be beneficial to a lot of our users.
> 
>> Two points…
>> 
>> 1) Putting it on `JSONDecoder` seems dubious since you’d only have access to 
>> `Decoder` (although conditional casting could solve that). It seems adding 
>> the method to `Decoder` and using `Decoder.Unevaluated.self` as the 
>> requested type, would be more useful. A user could then conditionally cast 
>> that value to things like `[String: Any]` and possibly use its contents 
>> generically.
> Putting that on Decoder would require all Decoders to have an "unevaluated 
> type" representation, which may not be appropriate for all formats.
> Since this is very often a request when working with 3rd-party APIs which you 
> don’t control (and are rarely offered in more than one format, if that), 
> putting this directly on JSONDecoder seems reasonable — you’d only really 
> expect this representation if you’re decoding from JSON; if you’re encoding 
> to/from a different format, you’re likely in control of the data in those 
> formats.
> 
>> 2) Matching it with an equivalent on `Encoder` would be great as well.  We 
>> take in JSON that has “metaData” like one aforementioned exampled. We then 
>> have to send back the equivalent metadata during a subsequent update; 
>> without ever inspecting or altering the unevaluated data. Being able encode 
>> a `Decoder.Unevaluated` would solve that problem as well.
> Yes, we’d add an equivalent type on encode as well.
> 
>> 
>> 
>> ___
>> swift-users mailing list
>> swift-users@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-users
> 

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-29 Thread Itai Ferber via swift-users
Hi Kevin,

> On Jun 29, 2017, at 12:30 PM, Kevin Wooten via swift-users 
>  wrote:
> 
>> Hi Jon,
>> 
>> I just joined this mailing list and have tried to catch up on the 
>> history of this thread, so please excuse me if I’ve missed something.
>> 
>> I’m sorry the Codable API at the moment does not answer your needs — 
>> you’re clearly not the only one who’s run into this, so let’s see 
>> how we can work together to make the API better for everyone.
>> For one thing, in the case of grabbing a subtree of JSON as 
>> "unevaluated" or "unmapped" (as it appears to be in the metadata case), 
>> it should be fairly simple to add a `JSONDecoder.UnevaluatedJSON` type 
>> that will allow you to essentially decode that part of the tree as an 
>> `Any`. `JSONDecoder` would have knowledge of this type and would be able 
>> to return the subtree inside of it — you’d decode a property as 
>> `JSONDecoder.UnevaluatedJSON.self` and access the contents through `var 
>> value: Any?`, or something similar. This would be simple additive API, 
>> which although might not make it in the upcoming betas, should be fairly 
>> simple introduce. Would this solve that use case?
>> 
>> We’re also working on improving `NSISO8601DateFormatter`. I don’t 
>> think I saw it in any of your emails — what specific use case are you 
>> looking for that it doesn’t at the moment support?
>> 
>> — Itai
> 
> 
> Itai, 
> 
> Is this a formal solution that is going to be implemented? This would solve 
> just about every issue I currently have with Decodable.
I can’t make any promises at the moment — we’ve got a lot of high-priority 
things to fix before the Swift 4.0 release. However, this is something I’d 
certainly like to put through API review and eventually release, since this is 
clearly something that would be beneficial to a lot of our users.

> Two points…
> 
> 1) Putting it on `JSONDecoder` seems dubious since you’d only have access to 
> `Decoder` (although conditional casting could solve that). It seems adding 
> the method to `Decoder` and using `Decoder.Unevaluated.self` as the requested 
> type, would be more useful. A user could then conditionally cast that value 
> to things like `[String: Any]` and possibly use its contents generically.
Putting that on Decoder would require all Decoders to have an "unevaluated 
type" representation, which may not be appropriate for all formats.
Since this is very often a request when working with 3rd-party APIs which you 
don’t control (and are rarely offered in more than one format, if that), 
putting this directly on JSONDecoder seems reasonable — you’d only really 
expect this representation if you’re decoding from JSON; if you’re encoding 
to/from a different format, you’re likely in control of the data in those 
formats.

> 2) Matching it with an equivalent on `Encoder` would be great as well.  We 
> take in JSON that has “metaData” like one aforementioned exampled. We then 
> have to send back the equivalent metadata during a subsequent update; without 
> ever inspecting or altering the unevaluated data. Being able encode a 
> `Decoder.Unevaluated` would solve that problem as well.
Yes, we’d add an equivalent type on encode as well.

> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-29 Thread Kevin Wooten via swift-users
> Hi Jon,
> 
> I just joined this mailing list and have tried to catch up on the 
> history of this thread, so please excuse me if I’ve missed something.
> 
> I’m sorry the Codable API at the moment does not answer your needs — 
> you’re clearly not the only one who’s run into this, so let’s see 
> how we can work together to make the API better for everyone.
> For one thing, in the case of grabbing a subtree of JSON as 
> "unevaluated" or "unmapped" (as it appears to be in the metadata case), 
> it should be fairly simple to add a `JSONDecoder.UnevaluatedJSON` type 
> that will allow you to essentially decode that part of the tree as an 
> `Any`. `JSONDecoder` would have knowledge of this type and would be able 
> to return the subtree inside of it — you’d decode a property as 
> `JSONDecoder.UnevaluatedJSON.self` and access the contents through `var 
> value: Any?`, or something similar. This would be simple additive API, 
> which although might not make it in the upcoming betas, should be fairly 
> simple introduce. Would this solve that use case?
> 
> We’re also working on improving `NSISO8601DateFormatter`. I don’t 
> think I saw it in any of your emails — what specific use case are you 
> looking for that it doesn’t at the moment support?
> 
> — Itai


Itai, 

Is this a formal solution that is going to be implemented? This would solve 
just about every issue I currently have with Decodable.

Two points…

1) Putting it on `JSONDecoder` seems dubious since you’d only have access to 
`Decoder` (although conditional casting could solve that). It seems adding the 
method to `Decoder` and using `Decoder.Unevaluated.self` as the requested type, 
would be more useful. A user could then conditionally cast that value to things 
like `[String: Any]` and possibly use its contents generically.

2) Matching it with an equivalent on `Encoder` would be great as well.  We take 
in JSON that has “metaData” like one aforementioned exampled. We then have to 
send back the equivalent metadata during a subsequent update; without ever 
inspecting or altering the unevaluated data. Being able encode a 
`Decoder.Unevaluated` would solve that problem as well.


___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread Randy Eckenrode via swift-users
I assume this issue affects other implementations of Encoder and Decoder as 
well. The most obvious way to represent a key with multiple types is an enum, 
but enums don’t have their conformances to Codable generated automatically. 
It’s possible to write your own, but it can get a bit ugly (e.g., 
https://gist.github.com/kenada/9acbd7200cff3590bda5e83118f62523 
).

-- 
Randy

> On Jun 23, 2017, at 1:14 PM, Jon Shier via swift-users 
>  wrote:
> 
> Itai:
> 
> No need to apologize, I do appreciate the difficulties of designing this 
> entire feature as quickly and completely as was required. 
> 
> An intermediate JSON type would be a great fix, though most useful if it 
> exists outside of JSONDecoder so it's useful for encoding as well. As long as 
> it can be initialize from outside and decoded on its own, I think it could 
> solve much of that issue. 
> 
> 
> Jo 
> 
> On Jun 23, 2017, at 12:54 PM, Itai Ferber  > wrote:
> 
>> Hi Jon,
>> 
>> I just joined this mailing list and have tried to catch up on the history of 
>> this thread, so please excuse me if I’ve missed something.
>> 
>> I’m sorry the Codable API at the moment does not answer your needs — you’re 
>> clearly not the only one who’s run into this, so let’s see how we can work 
>> together to make the API better for everyone.
>> For one thing, in the case of grabbing a subtree of JSON as "unevaluated" or 
>> "unmapped" (as it appears to be in the metadata case), it should be fairly 
>> simple to add a JSONDecoder.UnevaluatedJSON type that will allow you to 
>> essentially decode that part of the tree as an Any. JSONDecoder would have 
>> knowledge of this type and would be able to return the subtree inside of it 
>> — you’d decode a property as JSONDecoder.UnevaluatedJSON.self and access the 
>> contents through var value: Any?, or something similar. This would be simple 
>> additive API, which although might not make it in the upcoming betas, should 
>> be fairly simple introduce. Would this solve that use case?
>> 
>> We’re also working on improving NSISO8601DateFormatter. I don’t think I saw 
>> it in any of your emails — what specific use case are you looking for that 
>> it doesn’t at the moment support?
>> 
>> — Itai
>> 
>> On 23 Jun 2017, at 9:24, Jon Shier via swift-users wrote:
>> 
>> David:
>>  I never called the design silly (though I think it’s inadequate for 
>> some important usage and makes some strange decisions), I was referring to 
>> the fact that the (apparent) official solution can’t actually decode all of 
>> the JSON people use. It’s the same reason I brought up 
>> NSISO8601DateFormatter. After years of using third party libraries or 
>> writing your own, limited, implementation, finally, finally there was an 
>> official solution from Apple. The official 8601 date formatter. Only, come 
>> to find out, it doesn’t actually handle all of 8601 and those third party 
>> libraries or custom implementations are still required if you venture 
>> outside supported scenarios. I’m concerned about the same thing happening 
>> here. Now, if JSONDecoder isn’t actually intended to serve as a general JSON 
>> parsing solution, which I think would be surprising to a lot people, then 
>> fair enough. Apple and the Swift team just need to be far more clear that 
>> that’s the case, rather letting everyone believe otherwise. And frankly, if 
>> that’s the case, I think a huge opportunity has been missed. At the same 
>> time, if / when an official solution for JSON parsing comes out, or an 
>> actual JSON representation, how will it interact with the previous 
>> implementation?
>>  These concerns, and the general concerns I expressed during the 
>> evolution review (which still exist) aside, this is fixable, if the Swift 
>> team is interested in doing so. However, if the limitations of JSONDecoder 
>> aren’t even seen as limitations, or interest in fixing them aren’t there, 
>> then there’s little point to continuing the discussion. Something as simple 
>> as an additional decode(_ type: from: Any) on JSONDecoder would solve the 
>> issues with decoding partially deserialized blobs or representations from 
>> other APIs. Something to help represent Any in Codable types might be 
>> useful, though I recognize that there isn’t any way to currently 
>> differentiate between Codable types and those just used by JSON. 
>>  All of that said, my concerns mainly lie within the JSON realm. Codable 
>> works great for serialization to disk or other scenarios where I can just 
>> deal with the Data result and not have to worry about weakly typed 
>> intermediate results. I’ll certainly be using it everywhere I can. And I’m 
>> super happy that conformance is generated by the compiler rather than 
>> manually, like we had to do with Objective-C for over a decade. Even the 
>> JSON side is useful if I can 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread Jon Shier via swift-users
Itai:

No need to apologize, I do appreciate the difficulties of designing this entire 
feature as quickly and completely as was required. 

An intermediate JSON type would be a great fix, though most useful if it exists 
outside of JSONDecoder so it's useful for encoding as well. As long as it can 
be initialize from outside and decoded on its own, I think it could solve much 
of that issue. 


Jo 

> On Jun 23, 2017, at 12:54 PM, Itai Ferber  wrote:
> 
> Hi Jon,
> 
> I just joined this mailing list and have tried to catch up on the history of 
> this thread, so please excuse me if I’ve missed something.
> 
> I’m sorry the Codable API at the moment does not answer your needs — you’re 
> clearly not the only one who’s run into this, so let’s see how we can work 
> together to make the API better for everyone.
> For one thing, in the case of grabbing a subtree of JSON as "unevaluated" or 
> "unmapped" (as it appears to be in the metadata case), it should be fairly 
> simple to add a JSONDecoder.UnevaluatedJSON type that will allow you to 
> essentially decode that part of the tree as an Any. JSONDecoder would have 
> knowledge of this type and would be able to return the subtree inside of it — 
> you’d decode a property as JSONDecoder.UnevaluatedJSON.self and access the 
> contents through var value: Any?, or something similar. This would be simple 
> additive API, which although might not make it in the upcoming betas, should 
> be fairly simple introduce. Would this solve that use case?
> 
> We’re also working on improving NSISO8601DateFormatter. I don’t think I saw 
> it in any of your emails — what specific use case are you looking for that it 
> doesn’t at the moment support?
> 
> — Itai
> 
> On 23 Jun 2017, at 9:24, Jon Shier via swift-users wrote:
> 
> David:
>   I never called the design silly (though I think it’s inadequate for 
> some important usage and makes some strange decisions), I was referring to 
> the fact that the (apparent) official solution can’t actually decode all of 
> the JSON people use. It’s the same reason I brought up 
> NSISO8601DateFormatter. After years of using third party libraries or writing 
> your own, limited, implementation, finally, finally there was an official 
> solution from Apple. The official 8601 date formatter. Only, come to find 
> out, it doesn’t actually handle all of 8601 and those third party libraries 
> or custom implementations are still required if you venture outside supported 
> scenarios. I’m concerned about the same thing happening here. Now, if 
> JSONDecoder isn’t actually intended to serve as a general JSON parsing 
> solution, which I think would be surprising to a lot people, then fair 
> enough. Apple and the Swift team just need to be far more clear that that’s 
> the case, rather letting everyone believe otherwise. And frankly, if that’s 
> the case, I think a huge opportunity has been missed. At the same time, if / 
> when an official solution for JSON parsing comes out, or an actual JSON 
> representation, how will it interact with the previous implementation?
>   These concerns, and the general concerns I expressed during the 
> evolution review (which still exist) aside, this is fixable, if the Swift 
> team is interested in doing so. However, if the limitations of JSONDecoder 
> aren’t even seen as limitations, or interest in fixing them aren’t there, 
> then there’s little point to continuing the discussion. Something as simple 
> as an additional decode(_ type: from: Any) on JSONDecoder would solve the 
> issues with decoding partially deserialized blobs or representations from 
> other APIs. Something to help represent Any in Codable types might be useful, 
> though I recognize that there isn’t any way to currently differentiate 
> between Codable types and those just used by JSON. 
>   All of that said, my concerns mainly lie within the JSON realm. Codable 
> works great for serialization to disk or other scenarios where I can just 
> deal with the Data result and not have to worry about weakly typed 
> intermediate results. I’ll certainly be using it everywhere I can. And I’m 
> super happy that conformance is generated by the compiler rather than 
> manually, like we had to do with Objective-C for over a decade. Even the JSON 
> side is useful if I can control both sides of the API, which makes Swift on 
> the server very powerful.
>   So if I seem overly strident in my expression here it’s because I 
> experience the pain of consuming poorly designed JSON in Swift on practically 
> a daily basis and had hoped that a native implementation would alleviate 
> that. That it doesn’t, for me and others, currently, is very disappointing. 
> That the Swift team doesn’t seem to see the current limitations as important 
> or at all is doubly so, since it seems like these issues will never be fixed. 
>  
> 
> 
> 
> Jon
> 
> 
>> On Jun 23, 2017, at 4:34 AM, David Hart  wrote:
>> 
>> 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread Itai Ferber via swift-users

Hi Jon,

I just joined this mailing list and have tried to catch up on the 
history of this thread, so please excuse me if I’ve missed something.


I’m sorry the Codable API at the moment does not answer your needs — 
you’re clearly not the only one who’s run into this, so let’s see 
how we can work together to make the API better for everyone.
For one thing, in the case of grabbing a subtree of JSON as 
"unevaluated" or "unmapped" (as it appears to be in the metadata case), 
it should be fairly simple to add a `JSONDecoder.UnevaluatedJSON` type 
that will allow you to essentially decode that part of the tree as an 
`Any`. `JSONDecoder` would have knowledge of this type and would be able 
to return the subtree inside of it — you’d decode a property as 
`JSONDecoder.UnevaluatedJSON.self` and access the contents through `var 
value: Any?`, or something similar. This would be simple additive API, 
which although might not make it in the upcoming betas, should be fairly 
simple introduce. Would this solve that use case?


We’re also working on improving `NSISO8601DateFormatter`. I don’t 
think I saw it in any of your emails — what specific use case are you 
looking for that it doesn’t at the moment support?


— Itai

On 23 Jun 2017, at 9:24, Jon Shier via swift-users wrote:


David:
	I never called the design silly (though I think it’s inadequate for 
some important usage and makes some strange decisions), I was 
referring to the fact that the (apparent) official solution can’t 
actually decode all of the JSON people use. It’s the same reason I 
brought up NSISO8601DateFormatter. After years of using third party 
libraries or writing your own, limited, implementation, finally, 
finally there was an official solution from Apple. The official 8601 
date formatter. Only, come to find out, it doesn’t actually handle 
all of 8601 and those third party libraries or custom implementations 
are still required if you venture outside supported scenarios. I’m 
concerned about the same thing happening here. Now, if JSONDecoder 
isn’t actually intended to serve as a general JSON parsing solution, 
which I think would be surprising to a lot people, then fair enough. 
Apple and the Swift team just need to be far more clear that that’s 
the case, rather letting everyone believe otherwise. And frankly, if 
that’s the case, I think a huge opportunity has been missed. At the 
same time, if / when an official solution for JSON parsing comes out, 
or an actual JSON representation, how will it interact with the 
previous implementation?
	These concerns, and the general concerns I expressed during the 
evolution review (which still exist) aside, this is fixable, if the 
Swift team is interested in doing so. However, if the limitations of 
JSONDecoder aren’t even seen as limitations, or interest in fixing 
them aren’t there, then there’s little point to continuing the 
discussion. Something as simple as an additional decode(_ type: from: 
Any) on JSONDecoder would solve the issues with decoding partially 
deserialized blobs or representations from other APIs. Something to 
help represent Any in Codable types might be useful, though I 
recognize that there isn’t any way to currently differentiate 
between Codable types and those just used by JSON.
	All of that said, my concerns mainly lie within the JSON realm. 
Codable works great for serialization to disk or other scenarios where 
I can just deal with the Data result and not have to worry about 
weakly typed intermediate results. I’ll certainly be using it 
everywhere I can. And I’m super happy that conformance is generated 
by the compiler rather than manually, like we had to do with 
Objective-C for over a decade. Even the JSON side is useful if I can 
control both sides of the API, which makes Swift on the server very 
powerful.
	So if I seem overly strident in my expression here it’s because I 
experience the pain of consuming poorly designed JSON in Swift on 
practically a daily basis and had hoped that a native implementation 
would alleviate that. That it doesn’t, for me and others, currently, 
is very disappointing. That the Swift team doesn’t seem to see the 
current limitations as important or at all is doubly so, since it 
seems like these issues will never be fixed.




Jon



On Jun 23, 2017, at 4:34 AM, David Hart  wrote:


On 23 Jun 2017, at 03:45, Jon Shier via swift-users 
> wrote:


	I’m sorry, are you complaining about my use of Codable instead of 
more precisely referring to the JSON endcode/decode functionality 
based on it in Foundation, or are you honestly trying to say that 
said functionality was never intended to be a general purpose JSON 
solution? If it’s not actually intended to handle all JSON you 
should probably call it something else.


Hi Jon,

First of all, I'd like to point out that I've found your tone to be 
quite rude. Calling the design of Codable, that has gotten a lot 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread Jon Shier via swift-users
Your gist is extremely interesting to me. I had tried something similar 
with Argo’s existing JSON enum, but was somewhat stymied by trying to decode it 
from an unkeyed container. I suppose I still don’t have a good grasp on all of 
the existing container types.



Jon


> On Jun 23, 2017, at 11:46 AM, Randy Eckenrode via swift-users 
>  wrote:
> 
>> 
>> On Jun 17, 2017, at 10:07 PM, Chris Anderson via swift-users 
>> > wrote:
>> 
>> Say I have a JSON object such as:
>> 
>>   {
>> "id": "4yq6txdpfadhbaqnwp3",
>> "email": "john@example.com ",
>> "name":"John Doe",
>> "metadata": {
>>   "link_id": "linked-id",
>>   "buy_count": 4
>> }
>>   }
>> 
>> And with a struct of:
>> 
>> struct User: Codable {
>>   var id: String
>>   var email: String
>>   var name: String
>> }
>> 
>> How can I decode the `metadata` field into a Dictionary?
>> 
>> I’ve tried doing things such as, in my struct,
>> 
>> var metadata: Dictionary
>> 
>> or
>> 
>> var metadata: [String: Any]
>> 
>> But I get the error 
>> 
>> MyPlayground.playground:3:7: note: cannot automatically synthesize 
>> 'Encodable' because '<>' does not conform to 'Encodable'
>>   var metadata: Dictionary 
>> 
>> A meta or metadata field on many APIs (such as www.stripe.com 
>> ) can contain whatever you want, and I still want to 
>> be able to process it on the Swift end. How can I store that meta data field 
>> into a Dictionary that I can parse apart manually after?
> 
> It’s possible, but you have to do most of the work yourself because you the 
> compiler can’t create implementations for you. See below for a possible 
> implementation. Note that I just ignore types I don’t handle. I also took a 
> stab at doing something general in this gist 
> (https://gist.github.com/kenada/069e121371eb8db41231edfcd4bd14a8 
> ), but it 
> doesn’t implement very robust error handling or support encoding. It also 
> doesn’t flatten down to Any/[Any]/[String: Any] (leaving it up to the user to 
> destructure the enum).
> 
> import Foundation
> 
> struct User: Codable {
> var id: String
> var email: String
> var name: String
> var metadata: [String: Any]
> 
> init(from decoder: Decoder) throws {
> let container = try decoder.container(keyedBy: StaticCodingKeys.self)
> self.id = try container.decode(String.self, forKey: .id)
> self.email = try container.decode(String.self, forKey: .email)
> self.name = try container.decode(String.self, forKey: .name)
> self.metadata = try User.decodeMetadata(from: 
> container.superDecoder(forKey: .metadata))
> }
> 
> func encode(to encoder: Encoder) throws {
> var container = encoder.container(keyedBy: StaticCodingKeys.self)
> try container.encode(self.id, forKey: .id)
> try container.encode(self.email, forKey: .email)
> try container.encode(self.name, forKey: .name)
> try encodeMetadata(to: container.superEncoder(forKey: .metadata))
> }
> 
>static func decodeMetadata(from decoder: Decoder) throws -> [String: Any] {
> let container = try decoder.container(keyedBy: DynamicCodingKeys.self)
> var result: [String: Any] = [:]
> for key in container.allKeys {
> if let double = try? container.decode(Double.self, forKey: key) {
> result[key.stringValue] = double
> } else if let string = try? container.decode(String.self, forKey: 
> key) {
> result[key.stringValue] = string
> }
> }
> return result
> }
> 
> func encodeMetadata(to encoder: Encoder) throws {
> var container = encoder.container(keyedBy: DynamicCodingKeys.self)
> for (key, value) in metadata {
> switch value {
> case let double as Double:
> try container.encode(double, forKey: 
> DynamicCodingKeys(stringValue: key)!)
> case let string as String:
> try container.encode(string, forKey: 
> DynamicCodingKeys(stringValue: key)!)
> default:
> fatalError("unexpected type")
> }
> }
> }
> 
> private enum StaticCodingKeys: String, CodingKey {
> case id, email, name, metadata
> }
> 
> private struct DynamicCodingKeys: CodingKey {
> var stringValue: String
> 
> init?(stringValue: String) {
> self.stringValue = stringValue
> }
> 
> var intValue: Int?
> 
> init?(intValue: Int) {
> self.init(stringValue: "")
> self.intValue = intValue
> }
> }
> }
> 
> let userJson = """
>   {
> "id": "4yq6txdpfadhbaqnwp3",
> "email": "john@example.com ",
> "name":"John Doe",
> 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread Jon Shier via swift-users
David:
I never called the design silly (though I think it’s inadequate for 
some important usage and makes some strange decisions), I was referring to the 
fact that the (apparent) official solution can’t actually decode all of the 
JSON people use. It’s the same reason I brought up NSISO8601DateFormatter. 
After years of using third party libraries or writing your own, limited, 
implementation, finally, finally there was an official solution from Apple. The 
official 8601 date formatter. Only, come to find out, it doesn’t actually 
handle all of 8601 and those third party libraries or custom implementations 
are still required if you venture outside supported scenarios. I’m concerned 
about the same thing happening here. Now, if JSONDecoder isn’t actually 
intended to serve as a general JSON parsing solution, which I think would be 
surprising to a lot people, then fair enough. Apple and the Swift team just 
need to be far more clear that that’s the case, rather letting everyone believe 
otherwise. And frankly, if that’s the case, I think a huge opportunity has been 
missed. At the same time, if / when an official solution for JSON parsing comes 
out, or an actual JSON representation, how will it interact with the previous 
implementation?
These concerns, and the general concerns I expressed during the 
evolution review (which still exist) aside, this is fixable, if the Swift team 
is interested in doing so. However, if the limitations of JSONDecoder aren’t 
even seen as limitations, or interest in fixing them aren’t there, then there’s 
little point to continuing the discussion. Something as simple as an additional 
decode(_ type: from: Any) on JSONDecoder would solve the issues with decoding 
partially deserialized blobs or representations from other APIs. Something to 
help represent Any in Codable types might be useful, though I recognize that 
there isn’t any way to currently differentiate between Codable types and those 
just used by JSON. 
All of that said, my concerns mainly lie within the JSON realm. Codable 
works great for serialization to disk or other scenarios where I can just deal 
with the Data result and not have to worry about weakly typed intermediate 
results. I’ll certainly be using it everywhere I can. And I’m super happy that 
conformance is generated by the compiler rather than manually, like we had to 
do with Objective-C for over a decade. Even the JSON side is useful if I can 
control both sides of the API, which makes Swift on the server very powerful.
So if I seem overly strident in my expression here it’s because I 
experience the pain of consuming poorly designed JSON in Swift on practically a 
daily basis and had hoped that a native implementation would alleviate that. 
That it doesn’t, for me and others, currently, is very disappointing. That the 
Swift team doesn’t seem to see the current limitations as important or at all 
is doubly so, since it seems like these issues will never be fixed.  



Jon


> On Jun 23, 2017, at 4:34 AM, David Hart  wrote:
> 
> 
> On 23 Jun 2017, at 03:45, Jon Shier via swift-users  > wrote:
> 
>>  I’m sorry, are you complaining about my use of Codable instead of more 
>> precisely referring to the JSON endcode/decode functionality based on it in 
>> Foundation, or are you honestly trying to say that said functionality was 
>> never intended to be a general purpose JSON solution? If it’s not actually 
>> intended to handle all JSON you should probably call it something else.
> 
> Hi Jon,
> 
> First of all, I'd like to point out that I've found your tone to be quite 
> rude. Calling the design of Codable, that has gotten a lot of work from Apple 
> and swift-evolution, as silly is insulting and can leave people hurt. If you 
> have found it lacking, please say so: we're all here to discuss any feedback 
> people have had with Swift. But please do so with respect for the people and 
> the work behind it.
> 
> Now, concerning Codable, I find its name quite apt. It was never intended to 
> be used a full JSON parser but as a strongly-typed Swift equivalent of 
> Objective-C's NSCoding, which is nothing more than a framework for 
> serializing and deserializing types into different file formats.
> 
> David.
> 
>> Jon
>> 
>>> On Jun 22, 2017, at 9:42 PM, Greg Parker >> > wrote:
>>> 
>>> 
 On Jun 22, 2017, at 6:00 PM, Jon Shier via swift-users 
 > wrote:
 
My main concern here is that, as Swift’s official JSON parsing method, 
 Codable should be able to handle any JSON representation and use and it 
 doesn’t. 
>>> 
>>> Is this true? Is Codable intended to be Swift's official JSON parsing 
>>> system? Is Codable intended to be a general-purpose JSON parsing system? 
>>> 
>>> My understanding was that Codable was 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread Randy Eckenrode via swift-users

> On Jun 17, 2017, at 10:07 PM, Chris Anderson via swift-users 
>  wrote:
> 
> Say I have a JSON object such as:
> 
>   {
> "id": "4yq6txdpfadhbaqnwp3",
> "email": "john@example.com ",
> "name":"John Doe",
> "metadata": {
>   "link_id": "linked-id",
>   "buy_count": 4
> }
>   }
> 
> And with a struct of:
> 
> struct User: Codable {
>   var id: String
>   var email: String
>   var name: String
> }
> 
> How can I decode the `metadata` field into a Dictionary?
> 
> I’ve tried doing things such as, in my struct,
> 
> var metadata: Dictionary
> 
> or
> 
> var metadata: [String: Any]
> 
> But I get the error 
> 
> MyPlayground.playground:3:7: note: cannot automatically synthesize 
> 'Encodable' because '<>' does not conform to 'Encodable'
>   var metadata: Dictionary 
> 
> A meta or metadata field on many APIs (such as www.stripe.com 
> ) can contain whatever you want, and I still want to 
> be able to process it on the Swift end. How can I store that meta data field 
> into a Dictionary that I can parse apart manually after?

It’s possible, but you have to do most of the work yourself because you the 
compiler can’t create implementations for you. See below for a possible 
implementation. Note that I just ignore types I don’t handle. I also took a 
stab at doing something general in this gist 
(https://gist.github.com/kenada/069e121371eb8db41231edfcd4bd14a8 
), but it 
doesn’t implement very robust error handling or support encoding. It also 
doesn’t flatten down to Any/[Any]/[String: Any] (leaving it up to the user to 
destructure the enum).

import Foundation

struct User: Codable {
var id: String
var email: String
var name: String
var metadata: [String: Any]

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StaticCodingKeys.self)
self.id = try container.decode(String.self, forKey: .id)
self.email = try container.decode(String.self, forKey: .email)
self.name = try container.decode(String.self, forKey: .name)
self.metadata = try User.decodeMetadata(from: 
container.superDecoder(forKey: .metadata))
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StaticCodingKeys.self)
try container.encode(self.id, forKey: .id)
try container.encode(self.email, forKey: .email)
try container.encode(self.name, forKey: .name)
try encodeMetadata(to: container.superEncoder(forKey: .metadata))
}

   static func decodeMetadata(from decoder: Decoder) throws -> [String: Any] {
let container = try decoder.container(keyedBy: DynamicCodingKeys.self)
var result: [String: Any] = [:]
for key in container.allKeys {
if let double = try? container.decode(Double.self, forKey: key) {
result[key.stringValue] = double
} else if let string = try? container.decode(String.self, forKey: 
key) {
result[key.stringValue] = string
}
}
return result
}

func encodeMetadata(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: DynamicCodingKeys.self)
for (key, value) in metadata {
switch value {
case let double as Double:
try container.encode(double, forKey: 
DynamicCodingKeys(stringValue: key)!)
case let string as String:
try container.encode(string, forKey: 
DynamicCodingKeys(stringValue: key)!)
default:
fatalError("unexpected type")
}
}
}

private enum StaticCodingKeys: String, CodingKey {
case id, email, name, metadata
}

private struct DynamicCodingKeys: CodingKey {
var stringValue: String

init?(stringValue: String) {
self.stringValue = stringValue
}

var intValue: Int?

init?(intValue: Int) {
self.init(stringValue: "")
self.intValue = intValue
}
}
}

let userJson = """
  {
"id": "4yq6txdpfadhbaqnwp3",
"email": "john@example.com",
"name":"John Doe",
"metadata": {
  "link_id": "linked-id",
  "buy_count": 4
}
  }
""".data(using: .utf8)!

let decoder = JSONDecoder()
let user = try! decoder.decode(User.self, from: userJson)
print(user)
// Prints: User(id: "4yq6txdpfadhbaqnwp3", email: "john@example.com", name: 
"John Doe", metadata: ["buy_count": 4.0, "link_id": "linked-id"])

let encoder = JSONEncoder()
let data = try! encoder.encode(user)
print(String(data: data, encoding: .utf8)!)
// Prints: 
{"email":"john@example.com","id":"4yq6txdpfadhbaqnwp3","metadata":{"link_id":"linked-id","buy_count":4},"name":"John
 Doe"}

-- 
Randy Eckenrode___

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-23 Thread David Hart via swift-users

> On 23 Jun 2017, at 03:45, Jon Shier via swift-users  
> wrote:
> 
>   I’m sorry, are you complaining about my use of Codable instead of more 
> precisely referring to the JSON endcode/decode functionality based on it in 
> Foundation, or are you honestly trying to say that said functionality was 
> never intended to be a general purpose JSON solution? If it’s not actually 
> intended to handle all JSON you should probably call it something else.

Hi Jon,

First of all, I'd like to point out that I've found your tone to be quite rude. 
Calling the design of Codable, that has gotten a lot of work from Apple and 
swift-evolution, as silly is insulting and can leave people hurt. If you have 
found it lacking, please say so: we're all here to discuss any feedback people 
have had with Swift. But please do so with respect for the people and the work 
behind it.

Now, concerning Codable, I find its name quite apt. It was never intended to be 
used a full JSON parser but as a strongly-typed Swift equivalent of 
Objective-C's NSCoding, which is nothing more than a framework for serializing 
and deserializing types into different file formats.

David.

> Jon
> 
>>> On Jun 22, 2017, at 9:42 PM, Greg Parker  wrote:
>>> 
>>> 
>>> On Jun 22, 2017, at 6:00 PM, Jon Shier via swift-users 
>>>  wrote:
>>> 
>>> My main concern here is that, as Swift’s official JSON parsing method, 
>>> Codable should be able to handle any JSON representation and use and it 
>>> doesn’t.
>> 
>> Is this true? Is Codable intended to be Swift's official JSON parsing 
>> system? Is Codable intended to be a general-purpose JSON parsing system? 
>> 
>> My understanding was that Codable was designed to serialize Swift types, not 
>> to be able to import arbitrary JSON text into Swift nor to interoperate with 
>> every existing JSON API.
>> 
>> 
>> -- 
>> Greg Parker gpar...@apple.com Runtime Wrangler
>> 
>> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-22 Thread Jon Shier via swift-users
I’m sorry, are you complaining about my use of Codable instead of more 
precisely referring to the JSON endcode/decode functionality based on it in 
Foundation, or are you honestly trying to say that said functionality was never 
intended to be a general purpose JSON solution? If it’s not actually intended 
to handle all JSON you should probably call it something else.


Jon

> On Jun 22, 2017, at 9:42 PM, Greg Parker  wrote:
> 
> 
>> On Jun 22, 2017, at 6:00 PM, Jon Shier via swift-users 
>> > wrote:
>> 
>>  My main concern here is that, as Swift’s official JSON parsing method, 
>> Codable should be able to handle any JSON representation and use and it 
>> doesn’t.
> 
> Is this true? Is Codable intended to be Swift's official JSON parsing system? 
> Is Codable intended to be a general-purpose JSON parsing system? 
> 
> My understanding was that Codable was designed to serialize Swift types, not 
> to be able to import arbitrary JSON text into Swift nor to interoperate with 
> every existing JSON API.
> 
> 
> -- 
> Greg Parker gpar...@apple.com  Runtime 
> Wrangler
> 
> 

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-22 Thread Greg Parker via swift-users

> On Jun 22, 2017, at 6:00 PM, Jon Shier via swift-users 
>  wrote:
> 
>   My main concern here is that, as Swift’s official JSON parsing method, 
> Codable should be able to handle any JSON representation and use and it 
> doesn’t.

Is this true? Is Codable intended to be Swift's official JSON parsing system? 
Is Codable intended to be a general-purpose JSON parsing system? 

My understanding was that Codable was designed to serialize Swift types, not to 
be able to import arbitrary JSON text into Swift nor to interoperate with every 
existing JSON API.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-22 Thread Tony Parker via swift-users
Hi Jon,

> On Jun 22, 2017, at 6:00 PM, Jon Shier  wrote:
> 
> Tony:
>   My main concern here is that, as Swift’s official JSON parsing method, 
> Codable should be able to handle any JSON representation and use and it 
> doesn’t. In fact, it can’t. If that’s considered okay by the designers of the 
> library and Apple itself, then fine. I think it’s silly (just like I think 
> it’s silly that, after years of waiting, NSISO8601DateFormatter doesn’t 
> actually support the full ISO 8601 standard) and does a disservice to 
> developers, but fine. For example, many JSON APIs (from the very worst to 
> some of the best) use a common reply structure:
> 
> {
>   “value” : { } or null
>   “error” : { } or null
> }
> 
> Having implemented a few of these using Argo, I usually follow a common 
> pattern:
> 
> struct APIResponse: Argo.Decodable {
>   let value: JSON?
>   let error: APIError?
> }
> 
> I then decode the response, check to see which of the parts is non-null, and 
> continue decoding based on that result. I decode the value based on the 
> generic type passed in, usually in an Alamofire response serializer. Codable 
> can sort of represent this, with this:
> 
> struct APIResponse: Decodable {
> let value: T?
> let error: String? // String as I haven’t defined an error type.
> }
> 
>   This works, AFAICT, but loses the rather important ability to inspect 
> the decoding result before attempting to decode the generic value. Codable 
> would be perfectly happy to return me an APIResponse with two nil values, 
> which is an invalid state for this API and should be an error. (As an aside, 
> defaulting all errors for optional values to nil is poor practice and we lose 
> some error fidelity there.) This is really just a symptom of Foundation not 
> having a real JSON limitation. But it’s doubly concerning that the JSON 
> representation it does have, Any, can’t be parsed by it’s own JSON decoder. 

Have you considered using an enum?

let jsonA = """
{
"key1" : 1
}
""".data(using: .utf8)!

let jsonB = """
{
"key2" : "foo"
}
""".data(using: .utf8)!

enum EitherOr : Decodable {
case A(Int)
case B(String)

private enum CodingKeys : CodingKey { case key1; case key2 }

init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
if c.contains(.key1) {
self = .A(try c.decode(Int.self, forKey: .key1))
} else if c.contains(.key2) {
self = .B(try c.decode(String.self, forKey: .key2))
} else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: 
[], debugDescription: "”))
}
}
}

let decoder = JSONDecoder()
let result1 = try! decoder.decode(EitherOr.self, from: jsonA)
print(result1)
let result2 = try! decoder.decode(EitherOr.self, from: jsonB)
print(result2)

A(1)
B("foo")

>   Dealing with data also limits Codable’s use for JSON to only things 
> that have data representation. For example, push notifications can contain 
> custom JSON payloads. On Apple platforms the push handler automatically 
> decodes this JSON before passing the result to the delegates in the app. In 
> the past I’ve been able to use the same JSON representations to parse the Any 
> returned by the push delegates as I do in my networking API, which gives me 
> exactly the same parsing for both methods. Codable can’t be used here. 
>   In addition, Codable’s cumbersome API for custom APIs is rather painful 
> to deal with, and the official recommended solution to use *Raw types that 
> come from your API and are used to initialize your “real” types is untenable 
> (on one project, every type I got in a response wouldn’t have required this, 
> forcing me to maintain 60 types, manually). Add to that the manual nature of 
> any sort of transform or validation, and Codable for real JSON decoding 
> becomes rather painful.
>   For me, this means that I’ll likely stick to libraries like Argo for 
> actual JSON decoding (greater fidelity and flexibility in far less code) and 
> use Codable for disk and other transfer representations (I look forward to 
> writing my watch communication using it) only, in all but the most ideal 
> circumstances (if I design the JSON API I can optimize it around Codable).
> 
> 
> Jon Shier

Sure, there is only so much we can do completely automatically. One of our 
goals was to make the simplest stuff possible with as little boilerplate as 
possible, but provide the ability to customize when you want to do something 
more advanced (as above).

- Tony

>   
> 
>> On Jun 22, 2017, at 7:10 PM, Tony Parker > > wrote:
>> 
>> Hi Jon,
>> 
>> Usually this boils down to a question of: what are you going to do with the 
>> Any?
>> 
>> If you intended to cast it to a dictionary and get at its values using 
>> string keys, then writing a struct with the 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-22 Thread Jon Shier via swift-users
Tony:
My main concern here is that, as Swift’s official JSON parsing method, 
Codable should be able to handle any JSON representation and use and it 
doesn’t. In fact, it can’t. If that’s considered okay by the designers of the 
library and Apple itself, then fine. I think it’s silly (just like I think it’s 
silly that, after years of waiting, NSISO8601DateFormatter doesn’t actually 
support the full ISO 8601 standard) and does a disservice to developers, but 
fine. For example, many JSON APIs (from the very worst to some of the best) use 
a common reply structure:

{
“value” : { } or null
“error” : { } or null
}

Having implemented a few of these using Argo, I usually follow a common pattern:

struct APIResponse: Argo.Decodable {
let value: JSON?
let error: APIError?
}

I then decode the response, check to see which of the parts is non-null, and 
continue decoding based on that result. I decode the value based on the generic 
type passed in, usually in an Alamofire response serializer. Codable can sort 
of represent this, with this:

struct APIResponse: Decodable {
let value: T?
let error: String? // String as I haven’t defined an error type.
}

This works, AFAICT, but loses the rather important ability to inspect 
the decoding result before attempting to decode the generic value. Codable 
would be perfectly happy to return me an APIResponse with two nil values, which 
is an invalid state for this API and should be an error. (As an aside, 
defaulting all errors for optional values to nil is poor practice and we lose 
some error fidelity there.) This is really just a symptom of Foundation not 
having a real JSON limitation. But it’s doubly concerning that the JSON 
representation it does have, Any, can’t be parsed by it’s own JSON decoder. 
Dealing with data also limits Codable’s use for JSON to only things 
that have data representation. For example, push notifications can contain 
custom JSON payloads. On Apple platforms the push handler automatically decodes 
this JSON before passing the result to the delegates in the app. In the past 
I’ve been able to use the same JSON representations to parse the Any returned 
by the push delegates as I do in my networking API, which gives me exactly the 
same parsing for both methods. Codable can’t be used here. 
In addition, Codable’s cumbersome API for custom APIs is rather painful 
to deal with, and the official recommended solution to use *Raw types that come 
from your API and are used to initialize your “real” types is untenable (on one 
project, every type I got in a response wouldn’t have required this, forcing me 
to maintain 60 types, manually). Add to that the manual nature of any sort of 
transform or validation, and Codable for real JSON decoding becomes rather 
painful.
For me, this means that I’ll likely stick to libraries like Argo for 
actual JSON decoding (greater fidelity and flexibility in far less code) and 
use Codable for disk and other transfer representations (I look forward to 
writing my watch communication using it) only, in all but the most ideal 
circumstances (if I design the JSON API I can optimize it around Codable).


Jon Shier


> On Jun 22, 2017, at 7:10 PM, Tony Parker  wrote:
> 
> Hi Jon,
> 
> Usually this boils down to a question of: what are you going to do with the 
> Any?
> 
> If you intended to cast it to a dictionary and get at its values using string 
> keys, then writing a struct with the properties you care about is the way we 
> recommend doing this. You don’t have to include every possible key.
> 
> There are some more dynamic behaviors possible with the Any, but the point of 
> this API was to try to move a lot of the parsing into a place where the 
> compiler could help you not only to generate the boilerplate but catch errors 
> at compile time.
> 
> The omission of an API to just get the rest of the data as some kind of Any 
> is both for reasons of abstraction (not every data format is JSON, and the 
> Any truly could be anything in other formats), and a statement of intent of 
> how we believe this API is best used.
> 
> - Tony
> 
>> On Jun 18, 2017, at 7:23 PM, Jon Shier via swift-users 
>> > wrote:
>> 
>> Given that, per his description, “metadata” can be anything, creating a 
>> struct doesn’t really help.
>> 
>> 
>> 
>> Jon Shier
>> 
>>> On Jun 18, 2017, at 9:00 PM, somu subscribe >> > wrote:
>>> 
>>> Create a struct for Metadata and conform to Coding
>>> 
>>> Code:
>>> 
>>> let string = """
>>> {
>>>   "id": "4yq6txdpfadhbaqnwp3",
>>>   "email": "john@example.com ",
>>>   "name":"John Doe",
>>>   "metadata": {
>>> "link_id": "linked-id",
>>> "buy_count": 4
>>>   }
>>> }
>>> """
>>> 
>>> let data = string.data(using: .utf8)! //Force 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-22 Thread Tony Parker via swift-users
Hi Jon,

Usually this boils down to a question of: what are you going to do with the Any?

If you intended to cast it to a dictionary and get at its values using string 
keys, then writing a struct with the properties you care about is the way we 
recommend doing this. You don’t have to include every possible key.

There are some more dynamic behaviors possible with the Any, but the point of 
this API was to try to move a lot of the parsing into a place where the 
compiler could help you not only to generate the boilerplate but catch errors 
at compile time.

The omission of an API to just get the rest of the data as some kind of Any is 
both for reasons of abstraction (not every data format is JSON, and the Any 
truly could be anything in other formats), and a statement of intent of how we 
believe this API is best used.

- Tony

> On Jun 18, 2017, at 7:23 PM, Jon Shier via swift-users 
>  wrote:
> 
> Given that, per his description, “metadata” can be anything, creating a 
> struct doesn’t really help.
> 
> 
> 
> Jon Shier
> 
>> On Jun 18, 2017, at 9:00 PM, somu subscribe > > wrote:
>> 
>> Create a struct for Metadata and conform to Coding
>> 
>> Code:
>> 
>> let string = """
>> {
>>   "id": "4yq6txdpfadhbaqnwp3",
>>   "email": "john@example.com ",
>>   "name":"John Doe",
>>   "metadata": {
>> "link_id": "linked-id",
>> "buy_count": 4
>>   }
>> }
>> """
>> 
>> let data = string.data(using: .utf8)! //Force unwrapping just for ease of 
>> explanation, use guard instead
>> 
>> struct User: Codable {
>> 
>> //Struct to handle the nested JSON
>> struct Metadata : Codable {
>> var linkID   : String
>> var buyCount : Int
>> 
>> //Customisation, if you want if you want your properties to be 
>> different from the JSON key
>> private enum CodingKeys : String, CodingKey {
>> case linkID = "link_id"
>> case buyCount   = "buy_count"
>> }
>> }
>> 
>> var id: String
>> var email: String
>> var name : String
>> var metadata : Metadata
>> }
>> 
>> let decoder = JSONDecoder()
>> 
>> do {
>> let user = try decoder.decode(User.self, from: data)
>> print(user)
>> }
>> catch {
>> print("error:\(error)")
>> }
>> 
>> Reference:
>> 
>> https://developer.apple.com/videos/play/wwdc2017/212/ 
>> 
>> 
>> 
>> Regards,
>> Muthu
>> 
>> 
>> 
>>> On 19 Jun 2017, at 3:29 AM, Jon Shier via swift-users 
>>> > wrote:
>>> 
>>> The more I use Codable, the less suited to networking it becomes. In 
>>> reading a variety of blog posts about implementing custom Decodable support 
>>> from JSON, I kept running across the same pattern. Basically, users had 
>>> started implementing their own decoding protocols which wrap Decodable 
>>> types, and have a type that represents the JSON representation and then 
>>> their real type, with an initializer connecting the two. But apparently 
>>> this is Apple’s official solution, which is rather terrible since it would 
>>> be completely unnecessary if the Decodable APIs were more flexible or we 
>>> could access keys by key path rather than nesting full containers. I can’t 
>>> image how much code I would have to add to decode the nasty JSON APIs I’ve 
>>> used Argo to parse before. Every type would need an underlying raw 
>>> representation that, at the very least, would need custom keys, lest I 
>>> pollute even those models with the terrible keys the JSON actually has. Not 
>>> to mention the various transforms I needed. Once I hit any reasonably 
>>> complex API, Argo is far far simpler to implement in fewer lines of code.
>>> In trying to make Argo’s JSON enum Decodable itself, I can’t seem to 
>>> find a way to access the Any representation of the raw JSON. In fact, it 
>>> appears there’s no way to represent an Any value in Codable at all, which 
>>> makes Codable rather useless for the scenarios like the one that prompted 
>>> this thread. Without such an ability it’s impossible to actually use 
>>> Codable with all of the JSON out there, where other solutions work just 
>>> fine. Argo’s JSON type is decodable by Argo, so you can use it to represent 
>>> a blob of JSON just fine. Other existing JSON frameworks have similar 
>>> solutions. 
>>> 
>>> 
>>> 
>>> Jon
>>> 
 On Jun 18, 2017, at 3:21 AM, Rien via swift-users > wrote:
 
 Dang, hit send too soon. Sorry.
 
 This does not address your question, so please ignore… (foot in mouth)!
 
 Regards,
 Rien
 
 Site: http://balancingrock.nl 
 Blog: http://swiftrien.blogspot.com 
 Github: http://github.com/Balancingrock 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-18 Thread Jon Shier via swift-users
Given that, per his description, “metadata” can be anything, creating a struct 
doesn’t really help.



Jon Shier

> On Jun 18, 2017, at 9:00 PM, somu subscribe  wrote:
> 
> Create a struct for Metadata and conform to Coding
> 
> Code:
> 
> let string = """
> {
>   "id": "4yq6txdpfadhbaqnwp3",
>   "email": "john@example.com ",
>   "name":"John Doe",
>   "metadata": {
> "link_id": "linked-id",
> "buy_count": 4
>   }
> }
> """
> 
> let data = string.data(using: .utf8)! //Force unwrapping just for ease of 
> explanation, use guard instead
> 
> struct User: Codable {
> 
> //Struct to handle the nested JSON
> struct Metadata : Codable {
> var linkID   : String
> var buyCount : Int
> 
> //Customisation, if you want if you want your properties to be 
> different from the JSON key
> private enum CodingKeys : String, CodingKey {
> case linkID = "link_id"
> case buyCount   = "buy_count"
> }
> }
> 
> var id: String
> var email: String
> var name : String
> var metadata : Metadata
> }
> 
> let decoder = JSONDecoder()
> 
> do {
> let user = try decoder.decode(User.self, from: data)
> print(user)
> }
> catch {
> print("error:\(error)")
> }
> 
> Reference:
> 
> https://developer.apple.com/videos/play/wwdc2017/212/ 
> 
> 
> 
> Regards,
> Muthu
> 
> 
> 
>> On 19 Jun 2017, at 3:29 AM, Jon Shier via swift-users > > wrote:
>> 
>>  The more I use Codable, the less suited to networking it becomes. In 
>> reading a variety of blog posts about implementing custom Decodable support 
>> from JSON, I kept running across the same pattern. Basically, users had 
>> started implementing their own decoding protocols which wrap Decodable 
>> types, and have a type that represents the JSON representation and then 
>> their real type, with an initializer connecting the two. But apparently this 
>> is Apple’s official solution, which is rather terrible since it would be 
>> completely unnecessary if the Decodable APIs were more flexible or we could 
>> access keys by key path rather than nesting full containers. I can’t image 
>> how much code I would have to add to decode the nasty JSON APIs I’ve used 
>> Argo to parse before. Every type would need an underlying raw representation 
>> that, at the very least, would need custom keys, lest I pollute even those 
>> models with the terrible keys the JSON actually has. Not to mention the 
>> various transforms I needed. Once I hit any reasonably complex API, Argo is 
>> far far simpler to implement in fewer lines of code.
>>  In trying to make Argo’s JSON enum Decodable itself, I can’t seem to 
>> find a way to access the Any representation of the raw JSON. In fact, it 
>> appears there’s no way to represent an Any value in Codable at all, which 
>> makes Codable rather useless for the scenarios like the one that prompted 
>> this thread. Without such an ability it’s impossible to actually use Codable 
>> with all of the JSON out there, where other solutions work just fine. Argo’s 
>> JSON type is decodable by Argo, so you can use it to represent a blob of 
>> JSON just fine. Other existing JSON frameworks have similar solutions. 
>> 
>> 
>> 
>> Jon
>> 
>>> On Jun 18, 2017, at 3:21 AM, Rien via swift-users >> > wrote:
>>> 
>>> Dang, hit send too soon. Sorry.
>>> 
>>> This does not address your question, so please ignore… (foot in mouth)!
>>> 
>>> Regards,
>>> Rien
>>> 
>>> Site: http://balancingrock.nl 
>>> Blog: http://swiftrien.blogspot.com 
>>> Github: http://github.com/Balancingrock 
>>> Project: http://swiftfire.nl  - An HTTP(S) web server 
>>> framework in Swift
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
 On 18 Jun 2017, at 09:19, Rien > wrote:
 
 Are you looking for a general purpose JSON interpreter / API ?
 
 There are many of them around, and in fact I do have my own: 
 https://github.com/Balancingrock/VJson 
 
 
 With VJson I would write:
 
 let json = VJson.parse(… your json object…)
 
 and then access the metadata as:
 
 let buyCount = (json | ”metadata” | ”buy_count”)?.intValue
 
 or:
 
 var buyCount: Int &= json | “metadata” | “buy_count”
 
 To loop over the content of metadata:
 
 for item in (json | “metadata”) ?? [ ] {
print (item.nameValue)
switch item.type {
case .object: …
case .number: …
case .string: …
etc...
}
 }
 
 Obviously I am plugging my own 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-18 Thread somu subscribe via swift-users
Create a struct for Metadata and conform to Coding

Code:

let string = """
{
  "id": "4yq6txdpfadhbaqnwp3",
  "email": "john@example.com",
  "name":"John Doe",
  "metadata": {
"link_id": "linked-id",
"buy_count": 4
  }
}
"""

let data = string.data(using: .utf8)! //Force unwrapping just for ease of 
explanation, use guard instead

struct User: Codable {

//Struct to handle the nested JSON
struct Metadata : Codable {
var linkID   : String
var buyCount : Int

//Customisation, if you want if you want your properties to be 
different from the JSON key
private enum CodingKeys : String, CodingKey {
case linkID = "link_id"
case buyCount   = "buy_count"
}
}

var id: String
var email: String
var name : String
var metadata : Metadata
}

let decoder = JSONDecoder()

do {
let user = try decoder.decode(User.self, from: data)
print(user)
}
catch {
print("error:\(error)")
}

Reference:

https://developer.apple.com/videos/play/wwdc2017/212/ 



Regards,
Muthu



> On 19 Jun 2017, at 3:29 AM, Jon Shier via swift-users  
> wrote:
> 
>   The more I use Codable, the less suited to networking it becomes. In 
> reading a variety of blog posts about implementing custom Decodable support 
> from JSON, I kept running across the same pattern. Basically, users had 
> started implementing their own decoding protocols which wrap Decodable types, 
> and have a type that represents the JSON representation and then their real 
> type, with an initializer connecting the two. But apparently this is Apple’s 
> official solution, which is rather terrible since it would be completely 
> unnecessary if the Decodable APIs were more flexible or we could access keys 
> by key path rather than nesting full containers. I can’t image how much code 
> I would have to add to decode the nasty JSON APIs I’ve used Argo to parse 
> before. Every type would need an underlying raw representation that, at the 
> very least, would need custom keys, lest I pollute even those models with the 
> terrible keys the JSON actually has. Not to mention the various transforms I 
> needed. Once I hit any reasonably complex API, Argo is far far simpler to 
> implement in fewer lines of code.
>   In trying to make Argo’s JSON enum Decodable itself, I can’t seem to 
> find a way to access the Any representation of the raw JSON. In fact, it 
> appears there’s no way to represent an Any value in Codable at all, which 
> makes Codable rather useless for the scenarios like the one that prompted 
> this thread. Without such an ability it’s impossible to actually use Codable 
> with all of the JSON out there, where other solutions work just fine. Argo’s 
> JSON type is decodable by Argo, so you can use it to represent a blob of JSON 
> just fine. Other existing JSON frameworks have similar solutions. 
> 
> 
> 
> Jon
> 
>> On Jun 18, 2017, at 3:21 AM, Rien via swift-users  
>> wrote:
>> 
>> Dang, hit send too soon. Sorry.
>> 
>> This does not address your question, so please ignore… (foot in mouth)!
>> 
>> Regards,
>> Rien
>> 
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Balancingrock
>> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>>> On 18 Jun 2017, at 09:19, Rien  wrote:
>>> 
>>> Are you looking for a general purpose JSON interpreter / API ?
>>> 
>>> There are many of them around, and in fact I do have my own: 
>>> https://github.com/Balancingrock/VJson
>>> 
>>> With VJson I would write:
>>> 
>>> let json = VJson.parse(… your json object…)
>>> 
>>> and then access the metadata as:
>>> 
>>> let buyCount = (json | ”metadata” | ”buy_count”)?.intValue
>>> 
>>> or:
>>> 
>>> var buyCount: Int &= json | “metadata” | “buy_count”
>>> 
>>> To loop over the content of metadata:
>>> 
>>> for item in (json | “metadata”) ?? [ ] {
>>> print (item.nameValue)
>>> switch item.type {
>>> case .object: …
>>> case .number: …
>>> case .string: …
>>> etc...
>>> }
>>> }
>>> 
>>> Obviously I am plugging my own code here, but there are many others around, 
>>> I understand that SwiftyJSON is quite popular but I have not used that 
>>> myself.
>>> 
>>> Regards,
>>> Rien
>>> 
>>> Site: http://balancingrock.nl
>>> Blog: http://swiftrien.blogspot.com
>>> Github: http://github.com/Balancingrock
>>> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
 On 18 Jun 2017, at 04:07, Chris Anderson via swift-users 
  wrote:
 
 Say I have a JSON object such as:
 
 {
  "id": "4yq6txdpfadhbaqnwp3",
  "email": "john@example.com",
  "name":"John Doe",
  "metadata": {
"link_id": 

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-18 Thread Jon Shier via swift-users
The more I use Codable, the less suited to networking it becomes. In 
reading a variety of blog posts about implementing custom Decodable support 
from JSON, I kept running across the same pattern. Basically, users had started 
implementing their own decoding protocols which wrap Decodable types, and have 
a type that represents the JSON representation and then their real type, with 
an initializer connecting the two. But apparently this is Apple’s official 
solution, which is rather terrible since it would be completely unnecessary if 
the Decodable APIs were more flexible or we could access keys by key path 
rather than nesting full containers. I can’t image how much code I would have 
to add to decode the nasty JSON APIs I’ve used Argo to parse before. Every type 
would need an underlying raw representation that, at the very least, would need 
custom keys, lest I pollute even those models with the terrible keys the JSON 
actually has. Not to mention the various transforms I needed. Once I hit any 
reasonably complex API, Argo is far far simpler to implement in fewer lines of 
code.
In trying to make Argo’s JSON enum Decodable itself, I can’t seem to 
find a way to access the Any representation of the raw JSON. In fact, it 
appears there’s no way to represent an Any value in Codable at all, which makes 
Codable rather useless for the scenarios like the one that prompted this 
thread. Without such an ability it’s impossible to actually use Codable with 
all of the JSON out there, where other solutions work just fine. Argo’s JSON 
type is decodable by Argo, so you can use it to represent a blob of JSON just 
fine. Other existing JSON frameworks have similar solutions. 



Jon

> On Jun 18, 2017, at 3:21 AM, Rien via swift-users  
> wrote:
> 
> Dang, hit send too soon. Sorry.
> 
> This does not address your question, so please ignore… (foot in mouth)!
> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
> 
> 
> 
> 
> 
> 
> 
>> On 18 Jun 2017, at 09:19, Rien  wrote:
>> 
>> Are you looking for a general purpose JSON interpreter / API ?
>> 
>> There are many of them around, and in fact I do have my own: 
>> https://github.com/Balancingrock/VJson
>> 
>> With VJson I would write:
>> 
>> let json = VJson.parse(… your json object…)
>> 
>> and then access the metadata as:
>> 
>> let buyCount = (json | ”metadata” | ”buy_count”)?.intValue
>> 
>> or:
>> 
>> var buyCount: Int &= json | “metadata” | “buy_count”
>> 
>> To loop over the content of metadata:
>> 
>> for item in (json | “metadata”) ?? [ ] {
>>  print (item.nameValue)
>>  switch item.type {
>>  case .object: …
>>  case .number: …
>>  case .string: …
>>  etc...
>>  }
>> }
>> 
>> Obviously I am plugging my own code here, but there are many others around, 
>> I understand that SwiftyJSON is quite popular but I have not used that 
>> myself.
>> 
>> Regards,
>> Rien
>> 
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Balancingrock
>> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>>> On 18 Jun 2017, at 04:07, Chris Anderson via swift-users 
>>>  wrote:
>>> 
>>> Say I have a JSON object such as:
>>> 
>>> {
>>>   "id": "4yq6txdpfadhbaqnwp3",
>>>   "email": "john@example.com",
>>>   "name":"John Doe",
>>>   "metadata": {
>>> "link_id": "linked-id",
>>> "buy_count": 4
>>>   }
>>> }
>>> 
>>> And with a struct of:
>>> 
>>> struct User: Codable {
>>> var id: String
>>> var email: String
>>> var name: String
>>> }
>>> 
>>> How can I decode the `metadata` field into a Dictionary?
>>> 
>>> I’ve tried doing things such as, in my struct,
>>> 
>>> var metadata: Dictionary
>>> 
>>> or
>>> 
>>> var metadata: [String: Any]
>>> 
>>> But I get the error 
>>> 
>>> MyPlayground.playground:3:7: note: cannot automatically synthesize 
>>> 'Encodable' because '<>' does not conform to 'Encodable'
>>> var metadata: Dictionary 
>>> 
>>> A meta or metadata field on many APIs (such as www.stripe.com) can contain 
>>> whatever you want, and I still want to be able to process it on the Swift 
>>> end. How can I store that meta data field into a Dictionary that I can 
>>> parse apart manually after?
>>> 
>>> Thanks!
>>> 
>>> Chris Anderson
>>> 
>>> 
>>> 
>>> 
>>> 
>>> ___
>>> swift-users mailing list
>>> swift-users@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org

Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-18 Thread Jon Shier via swift-users
Your issue here is Any, which will likely never be Decodable. You’ll 
need an actual type to contain the raw JSON. Hilariously, I have to wonder if 
Argo’s JSON enum could be made Decodable, as it can represent every valid JSON 
type typically contained in the Any returned by JSONSerialization. Yet another 
reason why Swift needs a real JSON serialization.


Jon Shier

> On Jun 17, 2017, at 10:07 PM, Chris Anderson via swift-users 
>  wrote:
> 
> Say I have a JSON object such as:
> 
>   {
> "id": "4yq6txdpfadhbaqnwp3",
> "email": "john@example.com ",
> "name":"John Doe",
> "metadata": {
>   "link_id": "linked-id",
>   "buy_count": 4
> }
>   }
> 
> And with a struct of:
> 
> struct User: Codable {
>   var id: String
>   var email: String
>   var name: String
> }
> 
> How can I decode the `metadata` field into a Dictionary?
> 
> I’ve tried doing things such as, in my struct,
> 
> var metadata: Dictionary
> 
> or
> 
> var metadata: [String: Any]
> 
> But I get the error 
> 
> MyPlayground.playground:3:7: note: cannot automatically synthesize 
> 'Encodable' because '<>' does not conform to 'Encodable'
>   var metadata: Dictionary 
> 
> A meta or metadata field on many APIs (such as www.stripe.com 
> ) can contain whatever you want, and I still want to 
> be able to process it on the Swift end. How can I store that meta data field 
> into a Dictionary that I can parse apart manually after?
> 
> Thanks!
> 
> Chris Anderson
> 
>   
> 
> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-18 Thread Rien via swift-users
Dang, hit send too soon. Sorry.

This does not address your question, so please ignore… (foot in mouth)!

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift







> On 18 Jun 2017, at 09:19, Rien  wrote:
> 
> Are you looking for a general purpose JSON interpreter / API ?
> 
> There are many of them around, and in fact I do have my own: 
> https://github.com/Balancingrock/VJson
> 
> With VJson I would write:
> 
> let json = VJson.parse(… your json object…)
> 
> and then access the metadata as:
> 
> let buyCount = (json | ”metadata” | ”buy_count”)?.intValue
> 
> or:
> 
> var buyCount: Int &= json | “metadata” | “buy_count”
> 
> To loop over the content of metadata:
> 
> for item in (json | “metadata”) ?? [ ] {
>   print (item.nameValue)
>   switch item.type {
>   case .object: …
>   case .number: …
>   case .string: …
>   etc...
>   }
> }
> 
> Obviously I am plugging my own code here, but there are many others around, I 
> understand that SwiftyJSON is quite popular but I have not used that myself.
> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
> 
> 
> 
> 
> 
> 
> 
>> On 18 Jun 2017, at 04:07, Chris Anderson via swift-users 
>>  wrote:
>> 
>> Say I have a JSON object such as:
>> 
>>  {
>>"id": "4yq6txdpfadhbaqnwp3",
>>"email": "john@example.com",
>>"name":"John Doe",
>>"metadata": {
>>  "link_id": "linked-id",
>>  "buy_count": 4
>>}
>>  }
>> 
>> And with a struct of:
>> 
>> struct User: Codable {
>>  var id: String
>>  var email: String
>>  var name: String
>> }
>> 
>> How can I decode the `metadata` field into a Dictionary?
>> 
>> I’ve tried doing things such as, in my struct,
>> 
>> var metadata: Dictionary
>> 
>> or
>> 
>> var metadata: [String: Any]
>> 
>> But I get the error 
>> 
>> MyPlayground.playground:3:7: note: cannot automatically synthesize 
>> 'Encodable' because '<>' does not conform to 'Encodable'
>>  var metadata: Dictionary 
>> 
>> A meta or metadata field on many APIs (such as www.stripe.com) can contain 
>> whatever you want, and I still want to be able to process it on the Swift 
>> end. How can I store that meta data field into a Dictionary that I can parse 
>> apart manually after?
>> 
>> Thanks!
>> 
>> Chris Anderson
>> 
>>  
>> 
>> 
>> 
>> ___
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
> 

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-18 Thread Rien via swift-users
Are you looking for a general purpose JSON interpreter / API ?

There are many of them around, and in fact I do have my own: 
https://github.com/Balancingrock/VJson

With VJson I would write:

let json = VJson.parse(… your json object…)

and then access the metadata as:

let buyCount = (json | ”metadata” | ”buy_count”)?.intValue

or:

var buyCount: Int &= json | “metadata” | “buy_count”

To loop over the content of metadata:

for item in (json | “metadata”) ?? [ ] {
print (item.nameValue)
switch item.type {
case .object: …
case .number: …
case .string: …
etc...
}
}

Obviously I am plugging my own code here, but there are many others around, I 
understand that SwiftyJSON is quite popular but I have not used that myself.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift







> On 18 Jun 2017, at 04:07, Chris Anderson via swift-users 
>  wrote:
> 
> Say I have a JSON object such as:
> 
>   {
> "id": "4yq6txdpfadhbaqnwp3",
> "email": "john@example.com",
> "name":"John Doe",
> "metadata": {
>   "link_id": "linked-id",
>   "buy_count": 4
> }
>   }
> 
> And with a struct of:
> 
> struct User: Codable {
>   var id: String
>   var email: String
>   var name: String
> }
> 
> How can I decode the `metadata` field into a Dictionary?
> 
> I’ve tried doing things such as, in my struct,
> 
> var metadata: Dictionary
> 
> or
> 
> var metadata: [String: Any]
> 
> But I get the error 
> 
> MyPlayground.playground:3:7: note: cannot automatically synthesize 
> 'Encodable' because '<>' does not conform to 'Encodable'
>   var metadata: Dictionary 
> 
> A meta or metadata field on many APIs (such as www.stripe.com) can contain 
> whatever you want, and I still want to be able to process it on the Swift 
> end. How can I store that meta data field into a Dictionary that I can parse 
> apart manually after?
> 
> Thanks!
> 
> Chris Anderson
> 
>   
> 
> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

2017-06-17 Thread Chris Anderson via swift-users
Say I have a JSON object such as:

  {
"id": "4yq6txdpfadhbaqnwp3",
"email": "john@example.com",
"name":"John Doe",
"metadata": {
  "link_id": "linked-id",
  "buy_count": 4
}
  }

And with a struct of:

struct User: Codable {
  var id: String
  var email: String
  var name: String
}

How can I decode the `metadata` field into a Dictionary?

I’ve tried doing things such as, in my struct,

var metadata: Dictionary

or

var metadata: [String: Any]

But I get the error 

MyPlayground.playground:3:7: note: cannot automatically synthesize 'Encodable' 
because '<>' does not conform to 'Encodable'
  var metadata: Dictionary 

A meta or metadata field on many APIs (such as www.stripe.com) can contain 
whatever you want, and I still want to be able to process it on the Swift end. 
How can I store that meta data field into a Dictionary that I can parse apart 
manually after?

Thanks!

Chris Anderson





___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users