2016-02-18 3 views
1

Я пытался выяснить, как сохранить массивы словарей, используя типы Enum с NSCoding.Сохранить массив словарей с типом Enum, NSCoding

У меня есть перечисление с Medal типов

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) 

Как я бы для множества словарей с использованием нормальных значений (например, [String: 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

Спасибо за ваш ответ, я как раз собирался опубликовать свои собственные, потому что понял, что перечисление не является любым объектом. Я закончил поиск массива [[String: String]] и просто сохранил enum как Medal.Gold.rawValue в словаре. В очередной раз благодарим за помощь – crashoverride777