Попытка сохранить пользовательский объект в UserDefaults с помощью NSKeyedArchiver

Я хочу сохранить свой собственный объект класса в userdefault. Я пытаюсь сохранить это так:

class func setModel<T: Hashable>(model: T, key: String) {
    let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: model)
    UserDefaults.standard.set(encodedData, forKey: key)
    UserDefaults.standard.synchronize()
}

но приложение вылетает на первой строке этого метода с ошибкой:

NSForwarding: предупреждение: объект 0x600003944000 класса «DronesApp_Worker.WorkerProfileResponse» не реализует методSignatureForSelector: -- впереди проблемы Нераспознанный селектор - [DronesApp_Worker.WorkerProfileResponse replaceObjectForKeyedArchiver:]

Мой пользовательский класс объектов приведен ниже:

class WorkerProfileResponse: Codable, Hashable, Mappable{

    static func == (lhs: WorkerProfileResponse, rhs: WorkerProfileResponse) -> Bool {
        return lhs.id == rhs.id
    }

    override var hash: Int{
        return self.id!
    }

    var id, is_logged_in, last_login, last_active: Int?
    var username, email, mobile_number: String?
    var categoryName: String?
    var userCategories: [SelectedCategory]?
    var userSubCategories: [SelectedSubCategory]?
    var biometricToken: String?
    var accessToken: AccessToken?
    var userStatus: UserStatus?
    var userProfile: UserProfile?

    required init(map: Map) {

    }

    func mapping(map: Map) {
        id <- map["id"]
        is_logged_in <- map["is_logged_in"]
        last_login <- map["last_login"]
        last_active <- map["last_active"]
        biometricToken <- map["biometricToken"]
        username <- map["username"]
        email <- map["email"]
        mobile_number <- map["mobile_number"]
        accessToken <- map["accessToken"]
        userStatus <- map["userStatus"]
        userCategories <- map["userCategories"]
        userSubCategories <- map["userSubCategories"]
        userProfile <- map["userProfile"]
    }
}

person Faraz A. Khan    schedule 09.04.2020    source источник
comment
Не используйте NSKeyedArchiver, тем более что ваш тип уже соответствует Codable, просто используйте PropertyListEncoder или JSONEncoder, как описано в этом ответе.   -  person Dávid Pásztor    schedule 09.04.2020
comment
Я изменил эту строку: let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: model) на эту: let encodedData: Data = try! JSONEncoder().encode(model) И теперь она выдает мне ошибку: Тип аргумента 'T' не соответствует ожидаемому типу 'Encodable'   -  person Faraz A. Khan    schedule 09.04.2020
comment
Вам нужно изменить T:Hashable на T:Encodable в объявлении setModel.   -  person Dávid Pásztor    schedule 09.04.2020


Ответы (2)


Используйте JSONEncoder для сохранения данных в UserDefaults. Фиктивный код:

class YourClassName: Codable {
    //Your properties here

    func saveInPreference() {
        do {
            let jsonEncoder = JSONEncoder()
            UserDefaults.standard.set(try jsonEncoder.encode(Your object here), forKey: "Write UserDefaultKey here")
            UserDefaults.standard.synchronize()
        }
        catch {
            print(error.localizedDescription)
        }
    }
}

Надеюсь, это поможет!

@Faraz A. Khan прокомментируйте, если у вас есть какие-либо вопросы в приведенном выше фрагменте кода.

person Mohit Kumar    schedule 09.04.2020

Ошибка возникает из-за того, что требуется подкласс NSObject.

Как я уже упоминал в вашем предыдущем вопросе для использования NSKeyedArchiver класс должен быть подклассом NSObject и должен принять (и реализовать) NSCoding.

Еще раз: NSKeyedArchiver (относится к ObjC) не имеет ничего общего с Codable (относится к Swift).

person vadian    schedule 09.04.2020