Home > Blockchain >  Unexpected error: keyNotFound(CodingKeys(stringValue: "userFullName", intValue: nil) Error
Unexpected error: keyNotFound(CodingKeys(stringValue: "userFullName", intValue: nil) Error

Time:08-10

This is where I try to fetch and decode data inside ChatReceivedMessageModel. I do get data but while decoding I am getting codingkeys error.

  func listenDeleted() {
    socket?.off("deletedmessage")
    socket?.on("deletedmessage") { data, ack in
        let messageDict = data.last as! NSDictionary
        let messageDataObject = try? JSONSerialization.data(withJSONObject: messageDict, options: [])
        guard let messageData = messageDataObject else { return }
        do {
            let jsonDecoder = JSONDecoder()
            let message = try jsonDecoder.decode(ChatReceivedMessageModel.self, from: messageData)
            print("success")
            let messageID = message.messageId ?? ""
            let usertoConnect = message.userToConnect ?? ""
            let room = message.room ?? ""
            let userInfo = ["messageId": messageID]
            NotificationCenter.default.post(name: Notification.Name("messageDeleted"), object: nil, userInfo: userInfo)
        } catch {
            print("Unexpected error: \(error).")
        }
    }

That is the related model

class ChatReceivedMessageModel: Serializable {
var room: String?
var message: String?
var userToConnect: String?
var userFullName: String?
var senderId: String?
var senderPhotoUrl: String?
var creationTimestamp: Int64?
var messageId: String?

init(room: String, message: String, userToConnect: String, userFullName: String, senderId: String, senderPhotoUrl: String, creationTimestamp: Int64, messageId: String) {
    self.room = room
    self.message = message
    self.userToConnect = userToConnect
    self.userFullName = userFullName
    self.senderId = senderId
    self.senderPhotoUrl = senderPhotoUrl
    self.creationTimestamp = creationTimestamp
    self.messageId = messageId
}

enum CodingKeys: String, CodingKey {
    case room
    case message
    case userToConnect
    case userFullName
    case senderId
    case senderPhotoUrl
    case creationTimestamp
    case messageId
}

required init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    room = try values.decode(String.self, forKey: .room)
    message = try values.decodeIfPresent(String.self, forKey: .message)
    userToConnect = try values.decode(String.self, forKey: .userToConnect)
    userFullName = try values.decode(String.self, forKey: .userFullName)
    senderId =  try values.decode(String.self, forKey: .senderId)
    senderPhotoUrl = try values.decode(String.self, forKey: .senderPhotoUrl)
    creationTimestamp = try values.decode(Int64.self, forKey: .creationTimestamp)
    messageId = try values.decode(String.self, forKey: .messageId)
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(room, forKey: .room)
    try container.encode(message, forKey: .message)
    try container.encode(userToConnect, forKey: .userToConnect)
    try container.encode(userFullName, forKey: .userFullName)
    try container.encode(senderId, forKey: .senderId)
    try container.encode(senderPhotoUrl, forKey: .senderPhotoUrl)
    try container.encode(creationTimestamp, forKey: .creationTimestamp)
    try container.encode(messageId, forKey: .messageId)
}

func getChatUserModelType() -> ChatUserModel {
    var model = ChatUserModel()
    model.communityUserId = self.senderId
    model.name = self.userFullName
    model.photoUrl = self.senderPhotoUrl
    return model
  }
}

And the error is;

Unexpected error: keyNotFound(CodingKeys(stringValue: "userFullName", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "userFullName", intValue: nil) ("userFullName").", underlyingError: nil)).

I also added breakpoints outcome as in the image

enter image description here

CodePudding user response:

The problem is here

userFullName = try values.decode(String.self, forKey: .userFullName)

In the mentioned line you tell decoder to decode key named userFullName and throw an error if it doesn't exist and this happens when the key is not here like in your error and same also for any property that you define as optional but decode like a non-optional

You need to decode optionally with try? inside required init(from decoder: Decoder) throws {

userFullName = try? values.decode(String.self, forKey: .userFullName)

OR use decodeIfPresent

userFullName = try values.decodeIfPresent(String.self, forKey: .userFullName)

BTW in your current code you don't need implementation of any of these ones

1- enum CodingKeys: String, CodingKey { // You don't change any property name
2- required init(from decoder: Decoder) throws { // this occurs automatically when conform to Decodable/Codable
3- func encode(to encoder: Encoder) throws {  // this occurs automatically when conform to Encodable/Codable

So you can remove them completely from your current code

  • Related