iosswiftnscoder

Crash while decoding with NSCoder


I have two model classes for saving data, I am getting crash while decoding the data.

The first class:

class User: NSObject,NSCoding, Mappable {

    var authenticationToken: String?
    var _id: String?
    var email: String?
    var profilePhoto: String?
    var country: String?
    var contactNo: String?
    var occupation: String?
    var aboutMe: String?
    var role: RollType?
    var createdAt: String?
    var isActive: Bool?
    var avg: Double?
    var review: Review?
    var subscribe: subscriptionType?
    var isPayment: Bool?
    var payment: Float?
    var invoiceURL: String?
    var firstName: String?
    var lastName: String?
    var password: String?
    var pesaPal : [pesaPalData]?

    required init?(map: Map) {
        super.init()
        mapping(map: map)
    }

    override init() {
        super.init()
    }

    required init(coder aDecoder: NSCoder) {
        super.init()
        authenticationToken = aDecoder.decodeObject(forKey: "token") as? String
        _id = aDecoder.decodeObject(forKey: "_id") as? String
        email = aDecoder.decodeObject(forKey: "email") as? String
        profilePhoto = aDecoder.decodeObject(forKey: "profilePhoto") as? String
        country = aDecoder.decodeObject(forKey: "country") as? String
        contactNo = aDecoder.decodeObject(forKey: "contactNo") as? String
        occupation = aDecoder.decodeObject(forKey: "occupation") as? String
        aboutMe = aDecoder.decodeObject(forKey: "aboutMe") as? String
        role = RollType(rawValue: (aDecoder.decodeObject(forKey: "role") as! String))
        createdAt = aDecoder.decodeObject(forKey: "createdAt") as? String
        isActive = aDecoder.decodeObject(forKey: "isActive") as? Bool
        subscribe = subscriptionType(rawValue: (aDecoder.decodeObject(forKey: "subscribe") as! String))
        invoiceURL = aDecoder.decodeObject(forKey: "invoiceURL") as? String
        isPayment = aDecoder.decodeObject(forKey: "isPayment") as? Bool
        payment = aDecoder.decodeObject(forKey: "payment") as? Float
        firstName = aDecoder.decodeObject(forKey: "firstName") as? String
        lastName = aDecoder.decodeObject(forKey: "lastName") as? String
        pesaPal = aDecoder.decodeObject(forKey: "pesaPal") as? [pesaPalData]
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(authenticationToken, forKey: "token")

        aCoder.encode(_id, forKey: "_id")
        aCoder.encode(email, forKey: "email")
        aCoder.encode(profilePhoto, forKey: "profilePhoto")
        aCoder.encode(country, forKey: "country")
        aCoder.encode(contactNo, forKey: "contactNo")
        aCoder.encode(occupation, forKey: "occupation")
        aCoder.encode(aboutMe, forKey: "aboutMe")
        aCoder.encode(role?.rawValue, forKey: "role")
        aCoder.encode(createdAt, forKey: "createdAt")
        aCoder.encode(isActive, forKey: "isActive")
        aCoder.encode(subscribe?.rawValue, forKey: "subscribe")
        aCoder.encode(isPayment, forKey: "isPayment")
        aCoder.encode(payment, forKey: "payment")
        aCoder.encode(invoiceURL, forKey: "invoiceURL")
        aCoder.encode(firstName, forKey: "firstName")
        aCoder.encode(lastName, forKey: "lastName")
        aCoder.encode(pesaPal, forKey: "pesaPal")
    }

    func mapping(map: Map) {
        _id                     <- map["_id"]
        email                   <- map["email"]
        profilePhoto            <- map["profilePhoto"]
        country                 <- map["country"]
        contactNo               <- map["contactNo"]
        occupation              <- map["occupation"]
        aboutMe                 <- map["aboutMe"]
        role                    <- (map["role"],EnumTransform<RollType>())
        createdAt               <- map["createdAt"]
        isActive                <- map["isActive"]
        review                  <- map["review"]
        avg                     <- map["avg"]
        subscribe               <- map["subscribe"]
        isPayment               <- map["isPayment"]
        payment                 <- map["payment"]
        invoiceURL              <- map["invoiceURL"]
        firstName               <- map["firstName"]
        lastName                <- map["lastName"]
        password                <- map["password"]
        pesaPal                 <- map["pesapalDetails"]
    }
}

The second class:

class pesaPalData: NSObject, Mappable , NSCoding{

    var payment1 : String?
    var pesapalStatus : String?
    var reference : String?

    required init?(coder aDecoder: NSCoder) {
        payment1 = aDecoder.value(forKey: "paymentPesa") as? String
        pesapalStatus = aDecoder.value(forKey: "pesapalStatus") as? String
        reference = aDecoder.value(forKey: "reference") as? String
    }

    required init?(map: Map) {
        super.init()
        self.mapping(map: map)

    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(payment1, forKey: "paymentPesa")
        aCoder.encode(pesapalStatus, forKey: "pesapalStatus")
        aCoder.encode(reference, forKey: "reference")
    }

    func mapping(map: Map) {
        payment1               <- map["payment"]
        pesapalStatus          <- map["pesapalStatus"]
        reference              <- map["reference"]
    }


}

I am getting crash while decoding from the pespalData class :

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key paymentPesa

Help would be appreciated about what's causing the crash,

Thanks


Solution

  • Aren’t you calling the wrong method on the decoder? You should be calling decodeObject(forKey:), not value(forKey:).