使用枚举类型NSCoding保存字典数组

cra*_*777 1 arrays nscoding swift

我一直试图找出如何使用带有NSCoding的Enum类型保存字典数组.

我有一个奖章类型的枚举

enum Medal: String {
   case Unearned = "NoMedal"
   case Gold = "GoldMedal"
   case Silver = "SilverMedal"
}
Run Code Online (Sandbox Code Playgroud)

我的GameData.swift类中有一系列带有奖章类型的词典.

var medals: [[String: Medal]] = [
    ["1": .Unearned, "2": .Unearned, "3": .Unearned]
    ...
]
Run Code Online (Sandbox Code Playgroud)

比我在解码器方法中有这个代码

convenience required init?(coder decoder: NSCoder) {
    self.init()

    medals = decoder.decodeObjectForKey(Key.medals) as? [[String: Medal]] ?? medals
}
Run Code Online (Sandbox Code Playgroud)

这是编码器方法,我认为这是导致我的问题

// MARK: - Encode
func encodeWithCoder(encoder: NSCoder) {

    encoder.encodeObject(medals as? AnyObject, forKey: Key.medals)
}
Run Code Online (Sandbox Code Playgroud)

问题是重新启动它没有保存/加载奖牌阵列,它会一直重置为默认值.

我也尝试过这个

 encoder.encodeObject(medals as? [[String: Medal]], forKey: Key.medals)
Run Code Online (Sandbox Code Playgroud)

它会导致编译器错误.

我也不能使用常规语法

 encoder.encodeObject(medals, forKey: Key.medals)
Run Code Online (Sandbox Code Playgroud)

就像我对使用正常值的字典数组(例如[String:Int])一样,因为编译器也会抛出错误

Rob*_*ier 8

medals不是AnyObject,所以当你编码它时,as? AnyObject你得到nil.

仅仅因为枚举具有原始字符串值并不意味着您可以自动将其桥接到[String:String].你必须自己做.例如(使用Airspeed Velocity的版本mapValues):

convenience required init?(coder decoder: NSCoder) {
    self.init()

    if let medalStrings = decoder.decodeObjectForKey(Key.medals) as? [[String: String]] {
        medals = medalStrings.map { $0.mapValues { Medal(rawValue: $0) ?? .Unearned } }
    }

}

func encodeWithCoder(encoder: NSCoder) {
    let medalStrings = medals.map { $0.mapValues { $0.rawValue } }
    encoder.encodeObject(medalStrings, forKey: Key.medals)
}
Run Code Online (Sandbox Code Playgroud)