Start a new topic
Answered

CustomUser was working fine.. then just stopped out of no where

my user class...

 

class CustomUser: User, Codable {
    //open override func setValue(_ value: Any?, forUndefinedKey key: String) {}//have to put this in or i get a warning for every single variable
    
    var first_name: String?
    var last_name: String?
    var number: String?
    var companyName: String?
    var errorNotifications: Bool?
    var statusNotifications: Bool?
    var errorText: Bool?
    var statusText: Bool?
    var machines: Array<String>?
    
    var address: String?
    
    @available(*, deprecated, message: "Please use Swift.Codable instead")// says use Swift.Codable but there is no sign of any code examples actually using this
    override func mapping(map: Map) {
        super.mapping(map: map)
        first_name <- ("first_name", map["first_name"])
        last_name <- ("last_name", map["last_name"])
        number <- ("number", map["number"])
        companyName <- ("companyName", map["companyName"])
        errorNotifications <- ("errorNotifications", map["errorNotifications"])
        statusNotifications <- ("statusNotifications", map["statusNotifications"])
        errorText <- ("errotText", map["errorText"])
        statusText <- ("statusText", map["statusText"])
        machines <- ("machines", map["Machines"])
        
        address <- ("address", map["address"])
    }
    
}

 my AppDelegate


 

        Kinvey.sharedClient.userType = CustomUser.self

        Kinvey.sharedClient.initialize(
            appKey: "kid_S1_gbMQ0",
            appSecret: "21893ef7a99d446a89f9f75e6c4da15d"
        ) { 
            switch $0 {
            case .success(let user):
                if let user = user {
                    print("\(user.toJSON())")
                }
            case .failure(let error):
                print("\(error)")
            }
        }

        User.login(username: "username", password: "password", options: nil) { (result: Result<CustomUser, Swift.Error>) in
            switch result {
            case .success(let user):
                // The login was successful and the user is now the active user.
                // The credentials saved hide the login view and show main app content.
                print("usertype: \(Kinvey.sharedClient.userType)")

                print("user address: \(String(describing: user.address))")// returns nill
                print("user JSON: \(String(describing: user.toJSON()))")//only returns username, email, and metadata.

            case .failure(let error):
                // There was an error with the update save.
                print("error: \(error)")
            }
        }

 

returns just the very basic information in the JSON.


this was working completely fine.. then just stopped out of no where. I didn't change any code at all. 


what gives?


Best Answer

Hi Brad,


Yes, please use 'Codable' instead of 'Mappable' as suggested by Nick. Also, please try typecasting your user with your custom user class to get all the attributes as follows:

let myUser = Kinvey.sharedClient.activeUser as! CustomUser


Thanks,

Pranav


1 person has this question

I have the same issue. For what its worth, it seems the login method inside User.swift does actually get the correct JSON back. I saw "first_name" and "last_name" returned, those are my only custom attributes. The parsing must fail after that, because the CustomUser inside the Result<> has nil for both fields.

Brad Hughes, the solution to this issue is to update your CustomUser class to use Swift.Codable instead of the deprecated mapping method. Here is my new CustomUser class, and now the login correctly maps the custom attributes:


   

enum CustomCodingKeys : String, CodingKey {
        case first_name = "first_name"
        case last_name = "last_name"
}
    
// Swift.Decodable
required init(from decoder: Decoder) throws {
        // This maps the "_id", "_kmd" and "_acl" properties
        try super.init(from: decoder)
        let container = try decoder.container(keyedBy: CustomCodingKeys.self)

        first_name = try container.decodeIfPresent(String.self, forKey: .first_name)
        last_name = try container.decodeIfPresent(String.self, forKey: .last_name)
}
    
// Swift.Encodable
override func encode(to encoder: Encoder) throws {
        // This maps the "_id", "_kmd" and "_acl" properties
        try super.encode(to: encoder)
        var container = encoder.container(keyedBy: CustomCodingKeys.self)
        try container.encodeIfPresent(first_name, forKey: .first_name)
        try container.encodeIfPresent(last_name, forKey: .last_name)
}
    
/// Default Constructor
required init() {
        super.init()
}

@available(*, deprecated, message: "Please use Swift.Codable instead")
required init?(map: Map) {
    super.init(map: map)
}

   

Answer

Hi Brad,


Yes, please use 'Codable' instead of 'Mappable' as suggested by Nick. Also, please try typecasting your user with your custom user class to get all the attributes as follows:

let myUser = Kinvey.sharedClient.activeUser as! CustomUser


Thanks,

Pranav

Login or Signup to post a comment