2014-10-12 2 views
53

배경신속하게 NSCoder를 사용하여 enum을 어떻게 인코딩합니까?

나는 NSCoding 프로토콜을 사용하여 문자열 스타일의 열거를 인코딩하기 위해 노력하고 있어요,하지만 난에 변환 오류로 실행하고 다시 문자열에서하고 있습니다.

나는 다음과 같은 오류를 얻을 동안 디코딩 및 인코딩 : 전화

코드

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 
     } 

    // ... 

    } 
에 :

문자열

추가 인수 ForKey을 단계로 전환되지 않습니다

답변

57

열거 형을 원시 값과 변환해야합니다. 스위프트 1.2 (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") 
    } 

    // ... 

} 

스위프트 1.1 (엑스 코드 6.1), as 대신 as!의 사용

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

스위프트 1.0 (엑스 코드 6.0)를 사용 toRaw() 및 이 같은 fromRaw() : 엑스 코드 6.3, 스위프트 1.2

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

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

을! String은 결코 nil이 될 수없고'?? .DisplayAll'은 쓸모가 없습니다. 대신 'as'가되어서는 안됩니까? – Oren

+2

'as!'는 캐스트가 성공할 수 있도록 존재하는'String'을 형 변환합니다. 'Stage (rawValue : "someString")'는 문자열이 유효한 enum 값을 정의하지 않을 수도 있기 때문에 선택적을 반환합니다. 그 선택 사항을 풀어야합니다. * nil 병합 연산자 *는 선택 사항을 래핑되지 않은 버전으로 바꾸거나 옵션이없는 경우에는 'DisplayAll'으로 대체합니다. – vacawama

9

업데이트 :

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

노트 당신이 같이있는 경우 as!