Contexte
J'essaie d'encoder une énumération de style String à l'aide du protocole NSCoding, mais je rencontre des erreurs de conversion vers et depuis String.
J'obtiens les erreurs suivantes lors du décodage et de l'encodage:
La chaîne n'est pas convertible en scène
Argument supplémentaire ForKey: en appel
Code
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
}
// ...
}
Vous devez convertir l'énumération vers et depuis la valeur brute. Dans Swift 1.2 (Xcode 6.3), cela ressemblerait à ceci:
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), utilise as
au lieu de as!
:
self.stage = Stage(rawValue: (aDecoder.decodeObjectForKey( "stage" ) as String)) ?? .DisplayAll
Swift 1.0 (Xcode 6.0) utilise toRaw()
et fromRaw()
comme ceci:
self.stage = Stage.fromRaw(aDecoder.decodeObjectForKey( "stage" ) as String) ?? .DisplayAll
aCoder.encodeObject( self.stage.toRaw(), forKey:"stage" )
Mise à jour pour Xcode 6.3, Swift 1.2:
self.stage = Stage(rawValue: aDecoder.decodeObjectForKey("stage") as! String) ?? .DisplayAll
noter la as!
Voici une solution pour Swift 4.2. Comme indiqué dans les autres réponses, le problème est que vous essayez d'affecter directement la variable stage
avec une chaîne décodée et que vous essayez de transtyper la variable stage
en une chaîne dans la encodeWithCoder
méthode. Vous devez utiliser valeurs brutes à la place.
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.decodeInteger(forKey: "idx")
self.stage = Stage(rawValue: aDecoder.decodeObject(forKey: "stage") as String)
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encode(self.idx, forKey:"idx")
aCoder.encode(self.stage.rawValue, forKey:"stage")
}
// ...
}