简体   繁体   English

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

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

Sorry, if this is an easy question, but i couldn't find an answer for three days. 抱歉,如果这是一个简单的问题,但是我三天都找不到答案。 I'm just new to Swift. 我只是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. 问题:我想使用Swift-Enum-Type作为不同Swift-Dictionary的KEY,并以通用方式使用NSKeydArchiver保存此字典。

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) 首先,我展示了一些简单的枚举和字典示例代码(我知道,我可以将字典值作为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]

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. 这是我对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
}

So I would like to have some generic Type of Enums, like "AnyEnumType" in order to use that function in a generic way: 因此,我想拥有一些通用的枚举类型,例如“ AnyEnumType”,以便以通用方式使用该函数:

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

But this - of course - causes a Compiler-Error "Use of undeclared type "AnyEnumType"" 但这当然会导致编译器错误“使用未声明的类型“ AnyEnumType”

I tried a lot with typeAlias, with TypePlaceholders <T : Hashable> and so on, but I couldn't implement it. 我使用typeAlias,TypePlaceholders <T : Hashable>等进行了很多尝试,但是我无法实现它。

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

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 . 此外,你应该打电话给你列举HelloOptionshelloOptions ,并调用枚举值Option1 ,没有option1 All types in Swift should be capitalized. Swift中的所有类型均应大写。 You'll notice that this convention is followed religiously by the designers of Swift. 您会注意到,Swift的设计师认真地遵循了这个约定。 You should do so, too. 您也应该这样做。

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

相关问题 如何在 Swift 中实现通用约束? - How to implement a generic constraint in Swift? 如何使用一种通用方法遍历不同类型的词典? - How can I iterate through different types of dictionaries using one generic method? 如何在Swift中的泛型类上实现NSCoding? - How to implement NSCoding on a generic class in Swift? 在 Swift 中,如何通过为不同的键路径注册处理器来实现处理一个类型的通用系统? - In Swift, how can I implement a generic system that processes a type by registering processors for different key paths? 如何快速使用通用类型处理不同类型? - How can I handle different types using generic type in swift? 如何实现返回通用协议的通用Swift 2.2协议的方法 - How to implement a method of a generic Swift 2.2 protocol returning that generic protocol 如何在没有参数的情况下实现 Init()? 使用泛型枚举。 无法推断通用参数“T”。 迅速 - How to implement Init() with no parameters? Enum using Generics. Generic parameter 'T' could not be inferred. Swift 如何以通用方式快速访问关联枚举 - How to access associate enum in generic way in swift 如何实现通用 function 以在 Swift 中添加数字和字符串? - How to implement generic function for adding both numbers and String in Swift? 如何使用通用约束类型属性实现Swift协议? - How do I implement a Swift protocol with a generic constrained type property?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM