Сохранить Enums с NSUserDefaults, нераспознанный селектор - PullRequest
0 голосов
/ 30 октября 2018

У меня есть эти перечисления:

@objc enum Groups: Int {
    case large = 0
    case medium = 1
    case small = 2
    case micro = 3
    case all = 4
    case favoriten = 5
}

enum Ordering:String {
    case ascending
    case descending
    case nothing
}

enum QuantityStats:String {
    case one
    case two
    case three
    case four
    case six
}

enum KeysState: String {
    case listTableViewState
    case listLabelState
}

Это часть этого класса:

class ListTableViewState: State, NSCoding {

    private enum Keys: String {
        case group
        case statIntervalBase
        case order
        case quantityStats
    }

    var group: Groups {
        didSet {
            if initialized {

                saveUserDefaults(withKey: KeysState.listTableViewState.rawValue, myType: self)

            }
        }
    }
    var statIntervalBase: StatIntervalBaseModel
    var order: Ordering
    var searchParameter: String?
    var quantityStats: QuantityStats


    init(group: Groups, statIntervalBase: StatIntervalBaseModel, order: Ordering, searchParameter: String?, quantityStats: QuantityStats) {
        self.group = group
        self.statIntervalBase = statIntervalBase
        self.order = order
        self.searchParameter = searchParameter
        self.quantityStats = quantityStats

        print("Group", Keys.group, "order", Keys.order)

        super.init()
        initialized = true
    }


    required convenience init?(coder aDecoder: NSCoder) {
//        self.stage = Stage(rawValue: aDecoder.decodeObject(forKey: "stage") as String)
        let group = Groups(rawValue: aDecoder.decodeObject(forKey: Keys.group.rawValue) as! Int)
        let statIntervalBase = aDecoder.decodeObject(forKey: Keys.statIntervalBase.rawValue) as! StatIntervalBaseModel
        let order = Ordering(rawValue: aDecoder.decodeObject(forKey: Keys.order.rawValue) as! String)
        let quantityStats = QuantityStats(rawValue: aDecoder.decodeObject(forKey: Keys.quantityStats.rawValue) as! String)
        self.init(group: group!, statIntervalBase: statIntervalBase, order: order!, searchParameter: "", quantityStats: quantityStats!)

    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(group, forKey: Keys.group.rawValue)
        aCoder.encode(statIntervalBase, forKey: Keys.statIntervalBase.rawValue)
        aCoder.encode(order, forKey: Keys.order.rawValue)
        aCoder.encode(quantityStats, forKey: Keys.quantityStats.rawValue)
    }

}

Это класс State Base, который я сделал:

class State: NSObject {

    var initialized = false

    func saveUserDefaults<T>(withKey key: String, myType: T){

        let archiver:Data = NSKeyedArchiver.archivedData(withRootObject: myType)

        UserDefaults.standard.set(archiver, forKey: key)

        UserDefaults.standard.synchronize()
    }

    func loadUserDefaults<T>(withKey key: String) -> T? {
        var output: T?
        let decoded = UserDefaults.standard.object(forKey: key)
        if decoded != nil {
            let data = decoded as! Data
            output = (NSKeyedUnarchiver.unarchiveObject(with: data) as! T)
        } else {
            output = nil
        }

        return output
    }

}

Я хочу сохранить ListTableViewState с NSUserDefaults, но я продолжаю получать ошибки, я думаю, что неправильно сохраняю перечисления. Но я не мог понять, как это решить.

Это ошибка, которую я получаю:

2018-10-29 18: 53: 22.906915 + 0000 APP [40545: 8188629] - [_ SwiftValue encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x600001c7d7a0 2018-10-29 18: 53: 22.912060 + 0000 APP [40545: 8188629] * Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: '- [_ SwiftValue encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x600001c7d7a0' * Первый стек вызовов вызовов:

1 Ответ

0 голосов
/ 30 октября 2018

Вы создаете каждое значение перечисления из rawValue в вашем init(coder:). Почему бы вам не кодировать rawValue?

required convenience init?(coder aDecoder: NSCoder) {
    let group = Groups(rawValue: aDecoder.decodeInteger(forKey: Keys.group.rawValue))
    let statIntervalBase = aDecoder.decodeObject(forKey: Keys.statIntervalBase.rawValue) as! StatIntervalBaseModel
    let order = Ordering(rawValue: aDecoder.decodeObject(forKey: Keys.order.rawValue) as! String)
    let quantityStats = QuantityStats(rawValue: aDecoder.decodeObject(forKey: Keys.quantityStats.rawValue) as! String)
    self.init(group: group!, statIntervalBase: statIntervalBase, order: order!, searchParameter: "", quantityStats: quantityStats!)
}

func encode(with aCoder: NSCoder) {
    aCoder.encode(group.rawValue, forKey: Keys.group.rawValue)
    aCoder.encode(statIntervalBase, forKey: Keys.statIntervalBase.rawValue)
    aCoder.encode(order.rawValue, forKey: Keys.order.rawValue)
    aCoder.encode(quantityStats.rawValue, forKey: Keys.quantityStats.rawValue)
}

И я думаю, что вы можете написать loadUserDefaults(withKey:) как:

func loadUserDefaults<T>(withKey key: String) -> T? {
    var output: T? = nil

    if let data = UserDefaults.standard.data(forKey: key) {
        output = (NSKeyedUnarchiver.unarchiveObject(with: data) as! T)
    }

    return output
}

(Разве это не должно быть static?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...