Sorry, if this is an easy question, but i couldn't find an answer for three days. I'm just new to Swift.
Problem: I'd like to use the Swift-Enum-Type as the KEY for different Swift-Dictionaries AND save this dictionaries using NSKeydArchiver in a generic way.
First of all I show some easy sample code for the enum and dictionaries (I know, I could integrate the dictionaries values directly into the enum declaration as rawValues, but this is not my problem, my problem is to SAVE the dictionary with NSKeydArchiver -> see function below)
// ------------------------------------------------------
// Enumerations and Dictionaries
// ------------------------------------------------------
enum helloOptions {
case option1
case option2
case option3
}
enum someOtherEnum {
case green
case red
case blue
}
var myDictionary01 : Dictionary<helloOptions, String> = [helloOptions.option1 : "Hello", helloOptions.option2 : "Welcome", helloOptions.option3 : "Nice to see you"]
var myDictionary02 : Dictionary<someOtherEnum, Int> = [someOtherEnum.green : 22, someOtherEnum.red : 11, someOtherEnum.blue : 999]
And here is my working implementation of a savingFunction, but unfortunately it is not a generic way, because I would need to implement this function many times for all Enums in the App.
func saveDictionary(myDictionary: Dictionary<helloOptions, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool {
let completeDataPath = makeCompletePathToFile(myFileName, myDataFolder)
let saveSuccess : Bool = NSKeyedArchiver.archiveRootObject(myDictionary, toFile: completeDataPath)
if !saveSuccess {
println("Some problem saving Dictionary")
}
return saveSuccess
}
So I would like to have some generic Type of Enums, like "AnyEnumType" in order to use that function in a generic way:
func saveDictionary(myDictionary: Dictionary<AnyEnumType, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool {
...
}
But this - of course - causes a Compiler-Error "Use of undeclared type "AnyEnumType""
I tried a lot with typeAlias, with TypePlaceholders <T : Hashable>
and so on, but I couldn't implement it.
How can I implement the function like this
func saveDictionary(myDictionary: Dictionary<AnyKeyType, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool { ..
}
by declaring this generic Type "AnyKeyType" is following the protocol Hashable, Equitable, ... that enables me to use a String or a Enum.Member for Key ???
Something like this might work:
protocol EnumType {
typealias RawType
init?(rawValue: RawType)
var rawValue: RawType { get }
}
enum Hello: String, EnumType {
case Option1 = "Option1"
case Option2 = "Option2"
}
func toArchivableDictionaryWithEnumerationKeys<E: EnumType, T>(dictionary: Dictionary<E, T>) -> Dictionary<E.RawType, T> {
var result = Dictionary<E.RawType, T>()
// Tried to use reduce here, but couldn't make it work
for (key, value) in dictionary {
result[key.rawValue] = value
}
return result
}
func fromArchivedDictionaryWithEnumerationKeys<E: EnumType, T>(dictionary: Dictionary<E.RawType, T>) -> Dictionary<E, T>? {
var result = Dictionary<E, T>()
for (key, value) in dictionary {
if let enumKey = E(rawValue: key) {
result[enumKey] = value
} else {
return nil
}
}
return result
}
let dict = toArchivableDictionaryWithEnumerationKeys([Hello.Option1: "Bob"])
let data = NSKeyedArchiver.archivedDataWithRootObject(dict)
let value = NSKeyedUnarchiver.unarchiveObjectWithData(data) as Dictionary<String, String>
if let unarchived: Dictionary<Hello, String> = fromArchivedDictionaryWithEnumerationKeys(value) {
// Blah blah
}
Also, you should call your enumeration HelloOptions
not helloOptions
, and call the enumeration values Option1
, not option1
. All types in Swift should be capitalized. You'll notice that this convention is followed religiously by the designers of Swift. You should do so, too.