I need save a variable of type:
var array1: [AnyObject!] = []
I tried this but isn't save:
var key = "keySave"
var defaults = NSUserDefaults.standardUserDefaults()
array1.append(["key1": "val1", "key2": "val2"])
array1.append(["key2": "val3", "key4": "val4"])
defaults.setObject(array1, forKey: key)
defaults.synchronize()
Need I cast this variables to other type of data? What is the correct form to make this?
Thanks!
This is not allowed. According to the documentation of NSUserDefaults class, only these specific types are supported by setObject:forKey: method:
The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.
You can fix this by replacing a Swift array with NSMutableArray, a subclass of the allowed NSArray class.
Related
Is this proper syntax for this line of code? If not what would be the correct syntax and why so?
UserDefaults.standard.dictionary(forKey: "mainDict")?.updateValue(subDict, forKey: "subDictTitle")
First, you have to store Userdefault dictionary to a temporary dictionary. Then you have to add data to a temporary dictionary.
No need to update the dictionary to Userdefault. When you store Dictionary to the Usedefault with the same key, it will replace the older dictionary to the new one.
UserDefaults.standard.set(YOUR_TEMPORARY_DICTIONARY, forKey: YOUR_KEY_NAME)
The updateValue(_:forKey:) is a mutating instance method for the dictionary, which means that it updates the value of the dictionary. Obviously, In order to mutate an instance, it has to be mutable, which is not the case when calling UserDefaults.standard.dictionary(forKey: "mainDict").
Even if you did:
let myDict = ["k1": "Hello"]
UserDefaults.standard.register(defaults: ["myDict": myDict])
var mutable = UserDefaults.standard.dictionary(forKey: "myDict")!
mutable["k1"] = "HEY"
print(UserDefaults.standard.dictionary(forKey: "myDict")) // Optional(["k1": Hello])
the value of the dictionary set in the user default won't change because simply mutable is a copy of it.
To clarify, it's similar to implementing:
UserDefaults.standard.register(defaults: ["k2": "this is my string"])
UserDefaults.standard.string(forKey: "k2") = "new string"
which generates the error of
Expression is not assignable: function call returns immutable value
So, in order to resolve this issue, what you should do is to set a new value (updated dictionary) to the user defaults with the same key:
var myDict = UserDefaults.standard.dictionary(forKey: "myDict")
myDict?.updateValue("Hey", forKey: "k1")
UserDefaults.standard.set(myDict, forKey: "myDict")
I have a struct called trip:
struct trip {
var name: String
var description: String
var elements: [elementType] = []
}
elementType is a type declared in protocol.
Then I've declared an array called trips:
var trips: [trip] = []
The problem is that I have to save trips array to be able to show items after closing the app. First of all, I tried to use NSUserDefaults but it can save only few types and Any (type of struct) isn't one of them.
How can I save and restore this array?
You can only save NSData, NSString, NSNumber, NSDate, NSArray, and NSDictionary types in NSUserDefaults.
So you can add a init method inside the struct so that the data being created can be encoded and then stored in NSUserDefaults.
Follow the answer to this question: How to save struct to NSUserDefaults in Swift 2.0
I'm trying to save a dictionary to NSUserDefaults using the setObject() function but when I use the objectForKey() function to retrieve the dictionary it returns nil. Why is this happening?
var data = NSUserDefaults.standardUserDefaults();
var scoreboard = [Int : String]()
let scores = "scoresKey"
scoreboard[3] = "spencer"
scoreboard[6] = "brooke"
scoreboard[11] = "jason"
data.setObject(scoreboard, forKey: scores)
data.objectForKey(scores) // Returns nil
The first problem was that it's not possible to use NSUserDefaults in a Playground.
See: https://stackoverflow.com/a/31210205/3498950
A second problem is found when the code above runs in a normal iOS project. It throws an NSInvalidArgumentException since the dictionary was a non-property list object because the keys needed to be of type String.
Although NSDictionary and CFDictionary objects allow their keys to be
objects of any type, if the keys are not string objects, the
collections are not property-list objects.
See: "What is a Property List?" in the Apple Docs
I've a mutable dictionary (in form of [Int:Int]) and want that to save it. I would use NSUserDefaults like that:
var myDic: NSMutableDictionary = [:]
myDic = [1:2]
NSUserDefaults.standardUserDefaults().setObject(myDic, forKey: "myDic")
but with that I get an error:
Thread 1: signal SIGABRT
I have no idea why.
setObject(_:forKey:) can’t accept Dictionary with a key which is integer type. The method requires property-list objects, but myDic = [1:2] is not property-list object.
There are two documents about it.
setObject(_:forKey:) of NSUserDefaults
The value parameter can be only property list objects: NSData,
NSString, NSNumber, NSDate, NSArray, or NSDictionary. For
NSArray and NSDictionary objects, their contents must be property
list objects.
About Property Lists
And although NSDictionary and CFDictionary objects allow their keys to
be objects of any type, if the keys are not string objects, the
collections are not property-list objects.
If you set a integer-key to Dictionary, the Dictionary object cannot be used for a value of setObject. You have to use a string for the key like this:
myDic = ["1": 2]
I need save in NSUserDefaults an array or other structure of data to save objects with this format:
name = "myName", lastName = "myLastName"
I was trying to do this with an array of arrays but this can't save in NSUserDefaults.
Now I am trying with a custom class with structure to create objects and append to the array, but also get an error when trying to save this to NSUserDefaults. I need save with this structure, but I don't know what is the correct form. How would I do this?
var taskMgr: TaskManager = TaskManager()
struct task {
var name = "Un-Named"
var lastName = "Un-lastNamed"
}
class TaskManager: NSObject {
var tasks : [task] = []
func addTask(name : String, lastName: String){
tasks.append(task(name: name, lastName: desc))
}
}
NSUserDefaults expects the stored objects to all be property list objects, i.e. instances of NSArray, NSDictionary, NSString, NSNumber, NSData, or NSDate. Your struct isn't one of those. You'll need to convert your objects to property list types before you store them. One way to do that is to use NSKeyedArchiver and the NSCoding protocol to write your structs into an instance of NSData.