Save a tuple in NSUserDefaults

I’m using a tuple to store something like this.

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

Now I want to save it in NSUserDefaults.

  • Destructuring tuple of tuple in closure
  • Array of tuples in Swift
  • How can I convert an array to a tuple?
  • How to find the index of a tuple element from an tuple array? iOS, Swift
  • Obtain a pointer to a C char array in Swift
  • Tuple “upcasting” in Swift
  • NSUserDefaults.standardUserDefaults().setValue(accessLavels, forKey: "AccessLevelKey")
    NSUserDefaults.standardUserDefaults().synchronize()
    

    But I get the following error.

    Type ‘(hasInventoryAccess: Bool, hasPayrolAccess: Bool)’ does not conform to protocol ‘AnyObject’

    How can I resolve this issue? If its impossible, then any other suggestions to save a tuple is welcome.

    Thank you.

    5 Solutions Collect From Internet About “Save a tuple in NSUserDefaults”

    I encountered a similar scenario trying to encode a tuple with NSCoder. The way I am solving it is by manually converting the tuple to a Dictionary. This is not a great solution as the keys need to be changed in several places if the tuple ever changes.

    I had a nested enum in my tuple and gave it a base type (String) from which I converted the raw value. It was a little extra work but thankfully yours is only primitives.

    # 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)
    

    I had a tuple with 3 values.

    The following code was used for saving the tuple. Basically, I created a string from tuple (with components separated by a comma).

    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")
    }
    

    To retrieve the tuple, I retrieved the string, broke it into array and used the array to re-create a tuple.

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

    You can store Bool, Float, Int, Object, Double or URL but not a Tuple. So you have two
    options, save two only hasPayrolAccess and hasPayrolAccess Bool
    values:

    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)
    

    Or save it using an Array of 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)
        }
    }
    

    In the documentation, I don’t see any method -setValue.
    Based on the docs, NSUserDefaults is able to save NSString, NSNumber, NSData, NSDictionary, NSArray, NSData and NSDate only. Here is the link:
    NSUserDefaults Class Reference.

    So, you are not able to save tuple here. And -setValue is from NSKeyValueCodingprotocol.

    I’ts an year old question but still:

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

    In case you save only bools, let accesLvl : [String:Bool] is a better option.

    In case I don’t get something (I’m fairly new to Swift and programming altogether), what would be the benefit of using a “tuple” over a Dictionary, or even a struct