繁体   English   中英

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

[英]How to implement a generic way of saving different Dictionaries in Swift using NSKeyedArchiver?

抱歉,如果这是一个简单的问题,但是我三天都找不到答案。 我只是Swift的新手。

问题:我想使用Swift-Enum-Type作为不同Swift-Dictionary的KEY,并以通用方式使用NSKeydArchiver保存此字典。

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

// ------------------------------------------------------
// 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]

这是我对saveFunction的有效实现,但不幸的是,这不是通用的方式,因为我需要为App中的所有Enum多次实现此功能。

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
}

因此,我想拥有一些通用的枚举类型,例如“ AnyEnumType”,以便以通用方式使用该函数:

func saveDictionary(myDictionary: Dictionary<AnyEnumType, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool {
 ... 
}

但这当然会导致编译器错误“使用未声明的类型“ AnyEnumType”

我使用typeAlias,TypePlaceholders <T : Hashable>等进行了很多尝试,但是我无法实现它。

我如何实现这样的功能

func saveDictionary(myDictionary: Dictionary<AnyKeyType, AnyObject>, myFileName: String, myDataFolder: DataFolder) -> Bool { ..
}

通过声明此通用类型“ AnyKeyType”遵循协议Hashable,Equitable等,该协议使我能够将String或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
}

此外,你应该打电话给你列举HelloOptionshelloOptions ,并调用枚举值Option1 ,没有option1 Swift中的所有类型均应大写。 您会注意到,Swift的设计师认真地遵循了这个约定。 您也应该这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM