在NSUserDefaults中保存一个元组

时间:2015-01-12 06:44:32

标签: ios swift ios8 tuples nsuserdefaults

我使用元组存储这样的东西。

var accessLavels: (hasInventoryAccess: Bool, hasPayrolAccess: Bool)
accessLavels = (hasInventoryAccess: true, hasPayrolAccess: false)

现在我想将其保存在NSUserDefaults

NSUserDefaults.standardUserDefaults().setValue(accessLavels, forKey: "AccessLevelKey")
NSUserDefaults.standardUserDefaults().synchronize()

但我收到以下错误。

输入'(hasInventoryAccess:Bool,hasPayrolAccess:Bool)'不符合协议' AnyObject'

如何解决此问题?如果它不可能,那么欢迎任何其他保存元组的建议。

谢谢。

5 个答案:

答案 0 :(得分:7)

我遇到了类似的情况,尝试使用NSCoder对元组进行编码。我解决它的方法是手动将元组转换为Dictionary。这不是一个很好的解决方案,因为如果元组发生变化,需要在几个地方更改密钥。

我的元组中有一个嵌套的枚举,并给它一个基本类型(String),我从中转换了原始值。这是一个额外的工作,但幸运的是你的只是原始人。

# SerializeableTuple.swift

typealias AccessTuple = (hasInventoryAccess: Bool, hasPayrolAccess: Bool)
typealias AccessDictionary = [String: Bool]

let InventoryKey = "hasInventoryAccess"
let PayrollKey = "hasPayrollAccess"

func serializeTuple(tuple: AccessTuple) -> AccessDictionary {
    return [
        InventoryKey : tuple.hasInventoryAccess,
        PayrollKey : tuple.hasPayrolAccess
    ]
}

func deserializeDictionary(dictionary: AccessDictionary) -> AccessTuple {
    return AccessTuple(
        dictionary[InventoryKey] as Bool!,
        dictionary[PayrollKey] as Bool!
    )
}

# Encoding / Decoding

var accessLavels: AccessTuple = (hasInventoryAccess: true, hasPayrolAccess: false)

// Writing to defaults
let accessLevelDictionary = serializeTuple(accessLavels)
NSUserDefaults.standardUserDefaults().setObject(accessLevelDictionary, forKey: "AccessLevelKey")

// Reading from defaults
let accessDic = NSUserDefaults.standardUserDefaults().dictionaryForKey("AccessLevelKey") as AccessDictionary
let accessLev = deserializeDictionary(accessDic)

答案 1 :(得分:1)

  

您可以存储Bool,Float,Int,Object,Double或URL,但不能存储元组。所以你有两个   选项,只保存两个hasPayrolAccess和hasPayrolAccess Bool   值:

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "hasInventoryAccess")
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "hasPayrolAccess")
let hasInventoryAccess  = NSUserDefaults.standardUserDefaults().boolForKey("hasInventoryAccess")
println(hasInventoryAccess)

let hasPayrolAccess  = NSUserDefaults.standardUserDefaults().boolForKey("hasPayrolAccess")
println(hasPayrolAccess)
  

或使用Bool数组保存:

var accessLavels = [true,false]
println(accessLavels)
NSUserDefaults.standardUserDefaults().setValue(accessLavels, forKey: "accessLavels")
if let loadAccessLavels = NSUserDefaults.standardUserDefaults().arrayForKey("accessLavels") as? [Bool] {
    if let hasInventoryAccess = loadAccessLavels.first {
        println(hasInventoryAccess)
    }
    if let hasPayrolAccess = loadAccessLavels.last {
        println(hasPayrolAccess)
    }
}

答案 2 :(得分:1)

我有一个有3个值的元组。

以下代码用于保存元组。基本上,我从元组创建了一个字符串(用逗号分隔的组件)。

let defaultsLoad = NSUserDefaults.standardUserDefaults()
if appSingleton.runwayDestShared != nil
{
   // Creating a String from the tuple
   let runwayDestString = appSingleton.runwayDestShared!.0 + "," + appSingleton.runwayDestShared!.1  + "," + appSingleton.runwayDestShared!.2
   defaultsLoad.setObject(runwayDestString, forKey: "RunwayDest")
}

要检索元组,我检索了字符串,将其分解为数组并使用该数组重新创建元组。

let runwayDestString = defaultsLoad.stringForKey("RunwayDest")
if let runwayDestString = runwayDestString
{
    let runwayDestArray = runwayDestString.componentsSeparatedByString(",")
    appSingleton.runwayDestShared = (runwayDestArray[0],runwayDestArray[1],runwayDestArray[2])
}

答案 3 :(得分:0)

在文档中,我没有看到任何方法-setValue。 根据文档, NSUserDefaults 只能保存NSString,NSNumber,NSData,NSDictionary,NSArray,NSData和NSDate。链接在这里: NSUserDefaults Class Reference.

所以,你无法在这里保存元组。 -setValue来自NSKeyValueCoding协议。

答案 4 :(得分:0)

我还有一年的问题,但仍然:

 let accesLvl : [String:AnyObject] = ["hasInventoryAcces":true, "hasPayrolAccess":false]
 NSUserDefaults.standardUserDefaults().setObject(accesLvl, forKey: "accesLevel")

如果您只保存bool,let accesLvl : [String:Bool]是更好的选择。

如果我没有得到某些东西(我对Swift和完全编程相当新),使用“元组”而不是字典,甚至结构

会有什么好处?