2016-02-18 32 views
1

我一直在想出如何使用NSCoding使用枚舉類型保存字典數組。保存與Enum類型,NSCoding的字典數組

我有獎章類型

enum Medal: String { 
    case Unearned = "NoMedal" 
    case Gold = "GoldMedal" 
    case Silver = "SilverMedal" 
} 

我有我的GameData.swift類獎牌類型的字典的數組枚舉。

var medals: [[String: Medal]] = [ 
    ["1": .Unearned, "2": .Unearned, "3": .Unearned] 
    ... 
] 

比我在解碼方法

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

    medals = decoder.decodeObjectForKey(Key.medals) as? [[String: Medal]] ?? medals 
} 

此代碼,這是編碼器的方法,我相信是造成我的問題

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

    encoder.encodeObject(medals as? AnyObject, forKey: Key.medals) 
} 

的問題是重啓它不會保存/加載獎章數組,它會一直重置爲默認值。

我也試過這種

encoder.encodeObject(medals as? [[String: Medal]], forKey: Key.medals) 

,它會導致編譯錯誤。

我也不能像我將使用常規的語法

encoder.encodeObject(medals, forKey: Key.medals) 

使用正常值字典的陣列(例如[字符串:INT])作爲編譯器也將引發錯誤

+1

'enum's不是對象,所以它們不能作爲'AnyObject'被鑄造。嘗試將'[[String:Medal]]'轉換爲'[[String:String]]'並將其存儲。 – Mats

回答

6

medals不是AnyObject,所以當你編碼它as? AnyObject你得到nil

僅僅因爲枚舉具有原始字符串值並不意味着您可以自動將它橋接到[String:String]。你必須自己做。例如(使用Airspeed Velocity's version of 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) 
} 
+1

感謝您的回答我正要發佈自己的,因爲我意識到枚舉不是anyObject。我結束了一個[[String:String]]的數組,並將枚舉保存爲Medal.Gold.rawValue。再次感謝你的幫助 – crashoverride777