2014-10-12 2 views
53

фонКак кодировать перечисление с помощью NSCoder в swift?

Я пытаюсь кодировать перечисление строк в стиле с использованием протокола NSCoding, но я бегу на ошибки переходящих и обратно из String.

я получаю следующие ошибки во время декодирования и кодирования:

Строка не конвертируется в Stage

дополнительный аргумент ForKey: в вызове

Код

enum Stage : String 
    { 
     case DisplayAll = "Display All" 
     case HideQuarter = "Hide Quarter" 
     case HideHalf  = "Hide Half" 
     case HideTwoThirds = "Hide Two Thirds" 
     case HideAll  = "Hide All" 
    } 

    class AppState : NSCoding, NSObject 
    { 
     var idx = 0 
     var stage = Stage.DisplayAll 

     override init() {} 

     required init(coder aDecoder: NSCoder) { 
      self.idx = aDecoder.decodeIntegerForKey("idx" ) 
      self.stage = aDecoder.decodeObjectForKey( "stage") as String // ERROR 
     } 

     func encodeWithCoder(aCoder: NSCoder) { 
      aCoder.encodeInteger(self.idx,    forKey:"idx" ) 
      aCoder.encodeObject( self.stage as String, forKey:"stage") // ERROR 
     } 

    // ... 

    } 

ответ

57

Вам нужно преобразовать перечисление в исходное значение и из него. В Swift 1.2 (Xcode 6.3), то это будет выглядеть следующим образом:

class AppState : NSObject, NSCoding 
{ 
    var idx = 0 
    var stage = Stage.DisplayAll 

    override init() {} 

    required init(coder aDecoder: NSCoder) { 
     self.idx = aDecoder.decodeIntegerForKey("idx") 
     self.stage = Stage(rawValue: (aDecoder.decodeObjectForKey("stage") as! String)) ?? .DisplayAll 
    } 

    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeInteger(self.idx, forKey:"idx") 
     aCoder.encodeObject( self.stage.rawValue, forKey:"stage") 
    } 

    // ... 

} 

Swift 1.1 (Xcode 6.1), использует as вместо as!:

self.stage = Stage(rawValue: (aDecoder.decodeObjectForKey("stage") as String)) ?? .DisplayAll 

Swift 1.0 (Xcode 6.0) использует toRaw() и fromRaw() как это:

self.stage = Stage.fromRaw(aDecoder.decodeObjectForKey("stage") as String) ?? .DisplayAll 

    aCoder.encodeObject(self.stage.toRaw(), forKey:"stage") 
+0

Если у вас есть, как! то String никогда не может быть nil и '?? .DisplayAll' бесполезен. Разве это не должно быть «как?»? – Oren

+2

'as!' Отличает 'String', который существует, поэтому приведение будет успешным. 'Stage (rawValue:" someString ")' возвращает необязательный параметр, потому что строка может не определять действительное значение перечисления. Вы должны развернуть это необязательное. Оператор * nil coalescing * заменяет необязательный вариант с развернутой версией, если он существует, или '.DisplayAll', если это не так. – vacawama

9

Обновление для Xcode 6.3, Swift 1.2:

self.stage = Stage(rawValue: aDecoder.decodeObjectForKey("stage") as! String) ?? .DisplayAll 

примечанию as!