Generics 如何使用NSKeyedArchiver实现在Swift中保存不同词典的通用方法?

Generics 如何使用NSKeyedArchiver实现在Swift中保存不同词典的通用方法?,generics,dictionary,swift,nskeyedarchiver,Generics,Dictionary,Swift,Nskeyedarchiver,抱歉,如果这是一个简单的问题,但我三天都找不到答案。我刚接触斯威夫特 问题:我想使用Swift枚举类型作为不同Swift字典的键,并使用NSKeydArchiver以通用方式保存这些字典 首先,我展示了一些简单的enum和dictionary示例代码(我知道,我可以将dictionary值作为rawValues直接集成到enum声明中,但这不是我的问题,我的问题是使用NSKeydArchiver->参见下面的函数保存dictionary) //--------------------------

抱歉,如果这是一个简单的问题,但我三天都找不到答案。我刚接触斯威夫特

问题:我想使用Swift枚举类型作为不同Swift字典的键,并使用NSKeydArchiver以通用方式保存这些字典

首先,我展示了一些简单的enum和dictionary示例代码(我知道,我可以将dictionary值作为rawValues直接集成到enum声明中,但这不是我的问题,我的问题是使用NSKeydArchiver->参见下面的函数保存dictionary)

//------------------------------------------------------
//枚举和字典
// ------------------------------------------------------
枚举Helloopions{
案例选择1
案例选择2
案例选择3
}
枚举某人枚举{
果岭
壳红
箱蓝
}
var myDictionary01:Dictionary=[helloOptions.option1:“你好”,helloOptions.option2:“欢迎”,helloOptions.option3:“很高兴见到你”]
var myDictionary02:Dictionary=[someOtherEnum.green:22,someOtherEnum.red:11,someOtherEnum.blue:999]
这是我对savingFunction的工作实现,但不幸的是,这不是一种通用的方法,因为我需要为应用程序中的所有枚举多次实现此函数

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
}
func保存字典(myDictionary:Dictionary,myFileName:String,myDataFolder:DataFolder)->Bool{
让completeDataPath=makecompletedpathtofile(myFileName,myDataFolder)
让saveSuccess:Bool=NSKeyedArchiver.archiveRootObject(myDictionary,toFile:completeDataPath)
如果成功{
println(“保存字典的一些问题”)
}
返回saveSuccess
}
因此,我希望有一些通用类型的枚举,如“AnyEnumType”,以便以通用方式使用该函数:

func saveDictionary(myDictionary: Dictionary<AnyEnumType, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool {
 ... 
}
func保存字典(myDictionary:Dictionary,myFileName:String,myDataFolder:DataFolder)->Bool{
... 
}
当然,这会导致编译器错误“使用未声明的类型”AnyEnumType

我用typeAlias、TypePlaceholder
等做了很多尝试,但都没能实现

我如何实现这样的功能

func saveDictionary(myDictionary: Dictionary<AnyKeyType, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool { ..
}
func saveDictionary(myDictionary:Dictionary,myFileName:String,myDataFolder:DataFolder)->Bool{。。
}
通过声明这个泛型类型“AnyKeyType”遵循协议Hashable、equality、。。。
这使我能够使用字符串或Enum.Member作为键???

类似的方法可能会奏效:

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
}
协议枚举类型{
typealias原始类型
初始化?(rawValue:RawType)
var rawValue:RawType{get}
}
enum Hello:字符串,EnumType{
案例选项1=“选项1”
案例选项2=“选项2”
}
func to ArchivableDictionaryWithEnumerationKeys(字典:dictionary)->dictionary{
var result=Dictionary()
//尝试在此处使用reduce,但无法使其工作
用于字典中的(键、值){
结果[key.rawValue]=值
}
返回结果
}
func fromArchivedDictionaryWithEnumerationKeys(字典:dictionary)->字典?{
var result=Dictionary()
用于字典中的(键、值){
如果让enumKey=E(rawValue:key){
结果[enumKey]=值
}否则{
归零
}
}
返回结果
}
让dict=toArchivableDictionaryWithEnumerationKeys([Hello.Option1:“Bob”]))
让data=NSKeyedArchiver.archivedDataWithRootObject(dict)
让value=NSKeyedUnarchiver.unarchiveObjectWithData(data)作为字典
如果让未归档:Dictionary=fromArchivedDictionaryWithEnumerationKeys(值){
//废话
}
此外,您应该调用枚举
HelloOptions
而不是
HelloOptions
,并调用枚举值
Option1
,而不是
Option1
。Swift中的所有类型均应大写。你会注意到,Swift的设计师们虔诚地遵循着这个惯例。你也应该这样做

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
}