1

I have some JSON that I'm trying to decode with a Swift struct that conforms to the Codable protocol. The main struct doesn't seem to want to recognize the codingKey alias for thread_type, but happily consumes the explicitly named thread_id attribute. The struct in question is below:

struct Message: Codable {
var id: String?
var type: String?
var thread_id: String?
var threadType: String?
var sender: User?
var body: String?
var media: String?
var sentAt: Double?
var unread: Bool?
var status: String?
var url: String?

enum codingKeys: String, CodingKey {
    case id
    case type
    case thread_id
    case threadType = "thread_type"
    case sender
    case body
    case media
    case sentAt = "sent_at"
    case unread
    case status
    case url
}
}

The JSON that I'm trying to parse:

let json =
"""
{
"id": "Jvbl6LY",
"type": "sms",
"thread_id": "60LrVL7",
"thread_type": "578a",
"delay_until": null,
"sender": {
"id": "EVkdNBx",
"type": "user",
"first_name": "Jerry",
"last_name": "Ward",
"mobile_number": "123-456-7890",
"profile_image_url": "",
"is_online": false,
"email": "[email protected]"
},
"body": "Here is a picture of our Coquille Suite.  Let me know if you would like a reservation?",
"media": "",
"sent_at": 1509133604000.167,
"unread": false,
"status": "",
"url": "https://connect-staging.jypsee.com/api/sms/threads/60LrVL7/history/Jvbl6LY/"
}
"""

And finally the decoder call itself:

let decoder = JSONDecoder()
let data = json.data(using: .utf8)!
do {
    let message = try decoder.decode(Message.self, from: data)
    print(message.thread_id)
    print(message.threadType)
    print(message.sender?.firstName)
    print(message.sender?.lastName)
} catch {
    print(error)
}

The message.thread_id prints Optional("60LrVL7")\n" which is expected. The message.threadType prints nil\n, which is not expected. Even more bizarre is the fact that message.sender?.firstName and message.sender?.lastName both print "Optional("Jerry")\n" and "Optional("Ward")\n" respectively. Which means the nested User Codable Struct CodingKey IS working. I'm really at a loss as to why there's such an inconsistency in decoding.

Xcode Playground Gist is available here

5
  • 3
    CodingKeys, not codingKeys. Commented Oct 28, 2017 at 14:14
  • Doh! Amazing what an extra set of eyes can do. Thank you! Commented Oct 28, 2017 at 14:17
  • Is every field really optional? You can be sent {} and you would expect to decode that as all nils (and you'd consider those nils different than empty strings or false)? The fact that profile_image_url is being sent as "" makes that very suspicious. Using this many optionals is typically a sign of a data problem. Commented Oct 28, 2017 at 14:21
  • CodingKeys should be a private enum. Commented Mar 18, 2018 at 13:26
  • Should be, but they don't have to be for them to work. Commented Mar 18, 2018 at 13:27

1 Answer 1

3

Apple doc clearly states in the first sentence on the paragraph below. A special enumeration named 'CodingKeys' is necessary. (I had the similar problem and took me quite some time to find out).

enter image description here https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.