Re: [swift-users] Is there any way to decode from Any type JSON Object using JSONDecoder?

2017-06-28 Thread Masaki Haga via swift-users
(Added swift users as CC)

2017-06-24 3:47 GMT+09:00 Masaki Haga <hgmsk1...@gmail.com>:

> Hi Tony,
>
> Got it. Thank you very much for taking time for this.
>
> 2017-06-24 1:40 GMT+09:00 Tony Parker <anthony.par...@apple.com>:
>
>> Hi Masaki,
>>
>> Thanks for the additional info. I have a slightly different idea on how
>> to approach this which I think will be more performant. Let me work on that
>> and get back to you.
>>
>> - Tony
>>
>>
>> On Jun 22, 2017, at 7:51 PM, Masaki Haga <hgmsk1...@gmail.com> wrote:
>>
>> Hi Tony,
>>
>> Thank you very much for replying. Let me clarify what I was saying.
>>
>> Let’s say, we have a JSON like this:
>>
>> {
>> "badge": 1,
>> "content_available": false,
>> "mutable_content": false
>> }
>>
>> and to decode this JSON, we have to have a Codable model like below with
>> custom CodingKeys enum:
>>
>> struct APS: Codable {
>> enum CodingKeys: String, CodingKey {
>> case badge = "badge"
>> case contentAvailable = "content_available"
>> case mutableContent = "mutable_content"
>> }
>>
>> var badge: Int
>> var contentAvailable: Bool
>> var mutableContent: Bool
>> }
>>
>> This is a very small JSON so it is not hard to write this custom enum.
>> However, it is very cumbersome to define this enum in all of the
>> pre-existing models in our project to be able to decoded by Decodable and
>> we rather prefer just to have a model something like this:
>>
>> struct APS: Codable {
>> var badge: Int
>> var contentAvailable: Bool
>> var mutableContent: Bool
>> }
>>
>> To be able to decode this model with JSONDecoder, I wrote a JSON
>> converter like this:
>>
>> extension String {
>> var camelcased: String {
>> return self
>> .components(separatedBy: "_")
>> .enumerated()
>> .map { 0 == $0.offset ? $0.element : $0.element.capitalized }
>> .joined()
>> }
>> }
>> // This extension above was referenced from an article written in
>> Japanese: http://qiita.com/takasek/items/77955948fe283758ee55
>>
>> struct JSONCaseConverter {
>> public static func process(_ JSONObject: Any) -> Any {
>> if var dict = JSONObject as? [String: Any] {
>> for (key, value) in dict {
>> dict[key.camelcased] = process(value)
>> dict.removeValue(forKey: key)
>> }
>> return dict
>> } else if let array = JSONObject as? [Any] {
>> return array.map(process)
>> } else {
>> return JSONObject
>> }
>> }
>> }
>>
>> Basically, this JSONCaseConverter go though all the keys in a JSON and
>> convert the key from snake-case to camel-case so that the JSON can be
>> decoded directly with the model without custom CodingKeys enum.
>>
>> And then if we have a Data type JSON object (typically got from
>> URLSession.dataTask) and want to do some processing like this and decode
>> with JSONDecoder, we need to do:
>>
>> 1. Serialize Data object with JSONSerialization.jsonObject(with:) and
>> get Any type JSON Object
>> 2. do some processing  to the Any type JSON Object
>> 3. Serialize Any type Object with JSONSerialization.data(withJSONObject:)
>>  and get Data type JSON Object back.
>> 4. and then call JSONDecoder.decode().
>>
>> However, JSONSerialization.jsonObject(with:) is called again in
>> JSONDecoder.decode() implementation so there is a computational redundancy.
>>
>> Because I have already seen several this camel-case vs snake-case
>> discussion in some places including Swift Evolution, I guess not a small
>> number of developers will take the similar apploach ( I understand
>> automatic key renaming could be a unsafe operation and this is just my
>> personal opinion).
>>
>> Anyways, I was wondering if there is any way to opt-out the
>> JSONSerialization.jsonObject(with:) in JSONDecoder.decode(). And if not,
>> is it a good idea to have one more API such as `decode(_ type: T.Type,
>> from JSONObject: Any)` which I think gives more flexibility to the API?
>>
>> Regards,
>> - Masaki
>>
>> 2017-06-23 8:01 GMT+09:00 Tony Parker <anthony.par...@apple.com>:
>>
>>> Hi Masaki,
>>>
>

[swift-users] Is there any way to decode from Any type JSON Object using JSONDecoder?

2017-06-21 Thread Masaki Haga via swift-users
Hi Swift-Users,

I was wondering if there is any way to decode JSON from Any type JSON
Object using `JSONDecoder`, not from Data type object.

Currently, `JSONDecoder` has only one decode function which decodes Data
type object to `Decodable`. Inside the function, it serializes Data object
to Any Type JSON Object using `JSONSerialization` and pass it into
`_JSONDecoder(referencing:, options:)` (Refer JSONEncoder.swift#874).

As discussed in some of other threads such as "SE-0166: Swift Archival &
Serialization", the default implementation of JSONDecoder or Decodable
protocol doesn’t allow to decode from one format to another format (such as
snake-case to camel-case), we need to implement custom CodingKey enums.
However, in our project, to parse the server API JSON response with
snake-case, declaring custom CodingKey enums for all the pre-existing
models is almost impossible and very inefficient, so I decided to covert
all the JSON keys from snake-case to camel-case, and then pass it into
`JSONDecoder.decode`. To achieve this, we need to convert the Data object
resulted from `URLSession.task` to Any type JSON Object using
`JSONSerialization`, do the conversion from snake-case to camel-case and
then convert back to Data type and then pass to `JSONDecoder.decode` which
looks very redundant because the function uses `JSONSerialization` inside
of it as mentioned above. If there is a function like below, we can get rid
of this redundant call of `JSONSerialization`.

```
func decode(_ type: T.Type, from JSONObject: Any) throws -> T
```

Sorry if I am misunderstanding the new API but is there any way to decode
`Decodable` directly from Any type JSON Object?

If not, I think adding the function aforementioned and giving an ability to
opt-out this JSON serialization call would give more flexibility to the API
in my humble opinion.

Thank you for reading.

All the best,
- Masaki
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Is there any way to decode from Any type JSON Object using JSONDecoder?

2017-06-19 Thread Masaki Haga via swift-users
Hi Swift-Users,

I was wondering if there is any way to decode JSON from Any type JSON
Object using `JSONDecoder`, not from Data type object.

Currently, `JSONDecoder` has only one decode function which decodes Data
type object to `Decodable`. Inside the function, it serializes Data object
to Any Type JSON Object using `JSONSerialization` and pass it into
`_JSONDecoder(referencing:, options:)` (Refer JSONEncoder.swift#874).

As discussed in some of other threads such as "SE-0166: Swift Archival &
Serialization", the default implementation of JSONDecoder or Decodable
protocol doesn’t allow to decode from one format to another format (such as
snake-case to camel-case), we need to implement custom CodingKey enums.
However, in our project, to parse the server API JSON response with
snake-case, declaring custom CodingKey enums for all the pre-existing
models is almost impossible and very inefficient, so I decided to covert
all the JSON keys from snake-case to camel-case, and then pass it into
`JSONDecoder.decode`. To achieve this, we need to convert the Data object
resulted from `URLSession.task` to Any type JSON Object using
`JSONSerialization`, do the conversion from snake-case to camel-case and
then convert back to Data type and then pass to `JSONDecoder.decode` which
looks very redundant because the function uses `JSONSerialization` inside
of it as mentioned above. If there is a function like below, we can get rid
of this redundant call of `JSONSerialization`.

```
func decode(_ type: T.Type, from JSONObject: Any) throws -> T
```

Sorry if I am misunderstanding the new API but is there any way to decode
`Decodable` directly from Any type JSON Object?

If not, I think adding the function aforementioned and giving an ability to
opt-out this JSON serialization call would give more flexibility to the API
in my humble opinion.

Thank you for reading.

All the best,
- Masaki
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users