2014-10-12 19 views
53

SfondoCome si codifica enum utilizzando NSCoder in swift?

Sto cercando di codificare un enum String stile utilizzando il protocollo NSCoding, ma io sono in esecuzione in errori di conversione di andata e ritorno da stringa.

Ottengo i seguenti errori durante la decodifica e la codifica:

String non è convertibile in Fase

Extra argomento Forkey: in chiamata

Codice

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 
     } 

    // ... 

    } 

risposta

57

È necessario convertire l'enum in e dal valore grezzo. In Swift 1.2 (Xcode 6.3), questo sarebbe simile a questa:

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), utilizza as invece di as!:

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

Swift 1.0 (Xcode 6.0) utilizza toRaw() e fromRaw() come questo:

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

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

Se si dispone come! allora la stringa non può mai essere nulla e '?? .DisplayAll' è inutile. Non dovrebbe invece essere "come?" Invece? – Oren

+2

Il 'as!' Sta lanciando il 'String' che esiste così il cast avrà successo. 'Stage (rawValue:" someString ")' restituisce un opzionale poiché la stringa potrebbe non definire un valore enum valido. Devi scartare quello facoltativo. L'operatore * nil coalescing * sostituisce quello facoltativo con una versione unwrapped se esiste o '.DisplayAll' se non lo è. – vacawama

9

aggiornamento per Xcode 6.3, Swift 1.2:

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

nota la as!