I am trying to store an array to NSUserDefaults and retrieve the array when needed to populate a UITableView.
Currently I am using:
//store data
NSUserDefaults.standardUserDefaults().setObject(myArray, forKey: "\(identity.text!)listA")
NSUserDefaults.standardUserDefaults().synchronize()
//retrieve data
let tabledata = NSUserDefaults.standardUserDefaults().stringForKey("\(identity.text!)listA")
myArray = [tabledata!]
tableView.reloadData()
But I get
fatal error: unexpectedly found nil while unwrapping an Optional
value
when trying to load the data. I am not sure if the issue is in the storage or the retrieval. Has anyone been through this before?
From your code I see you are storing some array
// Your code
NSUserDefaults.standardUserDefaults().setObject(myArray, forKey: "\(identity.text!)listA")
and retrieving a string
//Your code
let tabledata = NSUserDefaults.standardUserDefaults().stringForKey("\(identity.text!)listA")
There is probably a type mismatch, You store one type and retrieve another type.
While retrieving either use arrayForKey() or objectForKey() see the code below.
let tabledata = NSUserDefaults.standardUserDefaults().arrayForKey("\(identity.text!)listA")
or
let tabledata = NSUserDefaults.standardUserDefaults().objectForKey("\(identity.text!)listA")
If it is an array I would go with First one.
Here are the way that you can store and retrieved array of object with help of NSKeyArchive.
To Store array to NSUserDefault.
let placesData = NSKeyedArchiver.archivedData(withRootObject: placesArray)
UserDefaults.standard.set(placesData, forKey: "places")
To Retrieved array from NSUserDefault.
let placesData = UserDefaults.standard.object(forKey: "places") as? NSData
if let placesData = placesData {
let placesArray = NSKeyedUnarchiver.unarchiveObject(with: placesData as Data) as? [Place]
print(placesArray)
}
Hope this help you.
Saving and Retrieving a String array to UserDefaults
Save array
let array = ["horse", "cow", "camel", "sheep", "goat"]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")
Retrieve array
let defaults = UserDefaults.standard
let array = defaults.object(forKey: "SavedStringArray") as? [String] ?? [String]()
See more at How to save user settings using NSUserDefaults
What are you storing in the array?
If it's objects it won't work, if It's just strings or numbers then it should be fine.
Next steps you take should be to turn on exception breakpoints and maybe println() everything you can so you can pinpoint the exact whereabouts of the problem.
As a shot in the dark I would suggest maybe (identity.text!) is coming out as nil
Also you should probably change it to this
if let tabledata: NSArray = NSUserDefaults.standardUserDefaults().stringForKey("\(identity.text!)listA"){
myArray = [tabledata!]
tableView.reloadData()
}
This will make the code not even try to run unless there is a value it can use
Latest swift3 version to store array of data into userdefaults and get that array of data using keys
let nameArray = ["Ramu","JAGAN","Steve","Swift"]
let namesArrayData = NSKeyedArchiver.archivedData(withRootObject: nameArray)
UserDefaults.standard.set(namesArrayData, forKey: "arrayData")
RetriveData
let retriveArrayData= UserDefaults.standard.object(forKey: "arrayData") as? NSData
if let retriveArrayData= namesArrayData{
let retriveArray = NSKeyedUnarchiver.unarchiveObject(with: namesArraydata as Data) as? [nameArray]
print(retriveArray )
}
This has been changed in swift 3.
Note that this works with device but not playground or simulator
//store the array
let array = ["horse", "cow", "camel", "sheep", "goat"]
let defaults = UserDefaults.standard
defaults.setValue(array, forKey: "history")
defaults.synchronize()
//Retrieve the array
if((UserDefaults.standard.array(forKey: "history")) != nil){
let historyWords = (UserDefaults.standard.array(forKey: "history") as? [String])!
print(historyWords)
}
Store into User Default:
let arrayFruit = ["Apple","Banana","Orange","Grapes","Watermelon"]
//store in user default
UserDefaults.standard.set(arrayFruit, forKey: "arrayFruit")
Retrieving array from User Defaults:
if let arr = UserDefaults.standard.array(forKey: "arrayFruit") as? [String]{
print(arr)
}
Related
I am saving data into userDeafults using 2 textfield as String, String but I want to know how to retrieve all the data to display either using loop or function
let save = UserDefaults.standard
let heading = headingText.text
let description = desxriptionTexr.text
save.set(description, forKey: heading!)
To get all keys and corresponding values in UserDefaults, you can use:
for (key, value) in UserDefaults.standard.dictionaryRepresentation() {
print("\(key) = \(value) \n")
}
In swift 3, you can store and retrieve using:
UserDefaults.standard.setValue(token, forKey: "user_auth_token")
print("\(UserDefaults.standard.value(forKey: "user_auth_token")!)")
I think is not a correct way to do.
I suggest you to put your values into a dictionary and set the dictionary into the UserDefaults.
let DictKey = "MyKeyForDictionary"
var userDefaults = UserDefaults.standard
// create your dictionary
let dict: [String : Any] = [
"value1": "Test",
"value2": 2
]
// set the dictionary
userDefaults.set(dict, forKey: DictKey)
// get the dictionary
let dictionary = userDefaults.object(forKey: DictKey) as? [String: Any]
// get value from
let value = dictionary?["value2"]
// iterate on all keys
guard let dictionary = dictionary else {
return
}
for (key, val) in dictionary.enumerated() {
}
If you have multiple Strings, simply save value as array
UserDefaults.standard.set(YourStringArray, forKey: "stringArr")
let arr = UserDefaults.standard.stringArray(forKey: "stringArr")
for s in arr! {
//do stuff
}
Here you are setting the key as heading and the value as description.
You can retrieve the value from userDefaults using UserDefaults.standard.object(forKey:), UserDefaults.standard.string(forKey: ),UserDefaults.standard.value(forKey: ) etc functions.
So its better to save heading and description for 2 different keys may be like
let save = UserDefaults.standard
let heading = headingText.text
let description = desxriptionTexr.text
save.set(description, forKey: "description")
save.set(heading, forKey: "heading")
And you could retrieve like
let description = UserDefaults.standard.string(forKey:"description")
let heading = UserDefaults.standard.string(forKey:"heading")
I am new to swift and trying to store NSMutableArray in Userdefaults. Here is what I am doinig :
//to save aaray in user defaults
var set:NSMutableArray = NSMutableArray(objects: self.listId)
self.saveListIdArray(set)
func saveListIdArray(_ params: NSMutableArray = []) {
let defaults = UserDefaults.standard
defaults.set(params, forKey: "ArrayKey")
defaults.synchronize()
}
//to get array from user default
func getUserDefaultKeyForAllObject(key userDefaultsKey: String) -> NSMutableArray {
let array = UserDefaults.standard.object(forKey: NSUserDefaultsKey.LIST_ID_ARRAY) as! NSMutableArray
print(array)
return array
}
App crashes with "fatal error: unexpectedly found nil while unwrapping an Optional value" exception.
Ignore the way I ask the question, help me out here.
Thank you.
Try converting to NSData then storing to nsuserdefaults like below
func saveListIdArray(_ params: NSMutableArray = []) {
let data = NSKeyedArchiver.archivedData(withRootObject: params)
UserDefaults.standard.set(data, forKey: "test")
UserDefaults.standard.synchronize()
}
For retrieving the data use
if let data = UserDefaults.standard.object(forKey: "test") as? Data {
if let storedData = NSKeyedUnarchiver.unarchiveObject(with: data) as? NSMutableArray
{
// In here you can access your array
}
}
You are force unwrapping the NSMutableArray for a key. Don't force unwrap when you try to get the value from a dictionary or UserDefault for a key because there may be a chance that the value does not exist for that key and force unwrapping will crash your app.
Do this as:
//to get array from user default
if let array = UserDefaults.standard.object(forKey:"ArrayKey") as? NSMutableArray
print(array)
}
I have 2 possible reasons for this:
You need to be 100% sure that you are retrieving array with the same key as you save it with. In your code you are saving the array with "ArrayKey" but retrieving it with NSUserDefaultsKey.LIST_ID_ARRAY, are you sure this is the same string?
What datatype is self.listId? If it's a custom class then you need to make that class conform to the nscoding protocol, then encode it to Data and save that to the userDefaults (Save custom objects into NSUserDefaults)
A 3rd reason is that you are trying to get an object from the defaults without ever writing anything to it. Try changing
let array = UserDefaults.standard.object(forKey: NSUserDefaultsKey.LIST_ID_ARRAY) as! NSMutableArray
print(array)
return array
to
if let array = UserDefaults.standard.object(forKey: "ArrayKey") as? NSMutableArray {
print(array)
return array
}
else {
return NSMutableArray()
}
I am trying to store an array to NSUserDefaults and retrieve the array when needed to populate a UITableView.
Currently I am using:
//store data
NSUserDefaults.standardUserDefaults().setObject(myArray, forKey: "\(identity.text!)listA")
NSUserDefaults.standardUserDefaults().synchronize()
//retrieve data
let tabledata = NSUserDefaults.standardUserDefaults().stringForKey("\(identity.text!)listA")
myArray = [tabledata!]
tableView.reloadData()
But I get
fatal error: unexpectedly found nil while unwrapping an Optional
value
when trying to load the data. I am not sure if the issue is in the storage or the retrieval. Has anyone been through this before?
From your code I see you are storing some array
// Your code
NSUserDefaults.standardUserDefaults().setObject(myArray, forKey: "\(identity.text!)listA")
and retrieving a string
//Your code
let tabledata = NSUserDefaults.standardUserDefaults().stringForKey("\(identity.text!)listA")
There is probably a type mismatch, You store one type and retrieve another type.
While retrieving either use arrayForKey() or objectForKey() see the code below.
let tabledata = NSUserDefaults.standardUserDefaults().arrayForKey("\(identity.text!)listA")
or
let tabledata = NSUserDefaults.standardUserDefaults().objectForKey("\(identity.text!)listA")
If it is an array I would go with First one.
Here are the way that you can store and retrieved array of object with help of NSKeyArchive.
To Store array to NSUserDefault.
let placesData = NSKeyedArchiver.archivedData(withRootObject: placesArray)
UserDefaults.standard.set(placesData, forKey: "places")
To Retrieved array from NSUserDefault.
let placesData = UserDefaults.standard.object(forKey: "places") as? NSData
if let placesData = placesData {
let placesArray = NSKeyedUnarchiver.unarchiveObject(with: placesData as Data) as? [Place]
print(placesArray)
}
Hope this help you.
Saving and Retrieving a String array to UserDefaults
Save array
let array = ["horse", "cow", "camel", "sheep", "goat"]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")
Retrieve array
let defaults = UserDefaults.standard
let array = defaults.object(forKey: "SavedStringArray") as? [String] ?? [String]()
See more at How to save user settings using NSUserDefaults
What are you storing in the array?
If it's objects it won't work, if It's just strings or numbers then it should be fine.
Next steps you take should be to turn on exception breakpoints and maybe println() everything you can so you can pinpoint the exact whereabouts of the problem.
As a shot in the dark I would suggest maybe (identity.text!) is coming out as nil
Also you should probably change it to this
if let tabledata: NSArray = NSUserDefaults.standardUserDefaults().stringForKey("\(identity.text!)listA"){
myArray = [tabledata!]
tableView.reloadData()
}
This will make the code not even try to run unless there is a value it can use
Latest swift3 version to store array of data into userdefaults and get that array of data using keys
let nameArray = ["Ramu","JAGAN","Steve","Swift"]
let namesArrayData = NSKeyedArchiver.archivedData(withRootObject: nameArray)
UserDefaults.standard.set(namesArrayData, forKey: "arrayData")
RetriveData
let retriveArrayData= UserDefaults.standard.object(forKey: "arrayData") as? NSData
if let retriveArrayData= namesArrayData{
let retriveArray = NSKeyedUnarchiver.unarchiveObject(with: namesArraydata as Data) as? [nameArray]
print(retriveArray )
}
This has been changed in swift 3.
Note that this works with device but not playground or simulator
//store the array
let array = ["horse", "cow", "camel", "sheep", "goat"]
let defaults = UserDefaults.standard
defaults.setValue(array, forKey: "history")
defaults.synchronize()
//Retrieve the array
if((UserDefaults.standard.array(forKey: "history")) != nil){
let historyWords = (UserDefaults.standard.array(forKey: "history") as? [String])!
print(historyWords)
}
Store into User Default:
let arrayFruit = ["Apple","Banana","Orange","Grapes","Watermelon"]
//store in user default
UserDefaults.standard.set(arrayFruit, forKey: "arrayFruit")
Retrieving array from User Defaults:
if let arr = UserDefaults.standard.array(forKey: "arrayFruit") as? [String]{
print(arr)
}
So I've been trying for a few hours for a way to store an array to NSUserDefault and print them to the cells but the data is not saving as an array, it basically only saves one value at a time.
var emailData = [String]()
var passwordData = [String]()
#IBAction func addPressed(sender: AnyObject) {
let defaults = NSUserDefaults.standardUserDefaults()
emailData.append(addEmail.text!)
passwordData.append(addPassword.text!)
var storedEmail = defaults.objectForKey("emailData") as? [String] ?? [String]()
var storedPasswords = defaults.objectForKey("passwordData") as? [String] ?? [String]()
// then update whats in the `NSUserDefault`
defaults.setObject(emailData, forKey: "emailData")
defaults.setObject(passwordData, forKey: "passwordData")
// call this after you update
defaults.synchronize() /*
NSUserDefaults.standardUserDefaults().setValue(addEmail.text, forKey: "email")
NSUserDefaults.standardUserDefaults().synchronize()
*/
}
So basically the data is not saving.
You can store Array too, by this way
let userDefault = NSUserDefaults.standardUserDefaults()
let arr = ["abc","xyz","pqr"]
userDefault.setObject(arr, forKey: "arr")
userDefault.synchronize()
let data = userDefault.objectForKey("arr") as! [String]
Save the Swift Array in Swift.
let kUserDefault = NSUserDefaults.standardUserDefaults()
kUserDefault.setObject(["KIRIT" , "MODI" , "FIRST" , "LAST"], forKey: "nameArray")
kUserDefault.synchronize()
Get Array
1. arrayForKey : You getting Swift Array
kUserDefault.arrayForKey("nameArray")!
2. objectForKey : You getting NSArray
kUserDefault.objectForKey("nameArray")!
3. valueForKey : You getting NSArray
kUserDefault.valueForKey("nameArray")
It is possible to store arrays in NSUserDefaults. But separating email and password in separate array is not suitable. You should store it as one object since they are related.
In your case an array of Dictionary objects is better, which is possible to store in NSUserDefaults as well, which you can retrieve as an array of Dictionary.
Here is the sample:
let userDefault = NSUserDefaults.standardUserDefaults()
var storedCredentials = userDefault.objectForKey("credentials") as? [[String:AnyObject]] ?? [[String:AnyObject]]()
let email =
[
"email" : addEmail.text!,
"password": addPassword.text!
]
storedCredentials.append(email)
userDefault.setObject(storedCredentials, forKey: "credentials")
userDefault.synchronize()
You can't save an array of [String] in NSUserDefault, if you look at the documentation :
For NSArray and NSDictionary objects, their contents must be property
list objects.
So what you can do is convert your [String] into NSData then save it into NSUserDefault.
// Store it as NSData
var emailData = [String]()
emailData.append("email1")
emailData.append("email2")
let emailIntoNSData = NSKeyedArchiver.archivedDataWithRootObject(emailData)
NSUserDefaults.standardUserDefaults().setObject(emailIntoNSData, forKey: "emailData")
// Retrieve it :
let emailFromNSData = NSUserDefaults.standardUserDefaults().objectForKey("emailData") as? NSData
if let emailFromNSData = emailFromNSData {
let emailArray = NSKeyedUnarchiver.unarchiveObjectWithData(emailFromNSData) as? [String]
if let emailArray = emailArray {
NSLog("Email Data : \(emailArray)") // ["email1","email2"]
// do something…
}
}
So I want to append an array in the NSUserDefaults, not save an entirely new one. The issue is that I want the array to be a logged history of a certain type of user interaction so I need to be appending an existing array in the NSUserDefaults, and not overwriting it.
i.e Not:
var data = [String]()
var questionsAsked = [String]()
func storeData() {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(questionsAsked, forKey: "questionsAsked")
defaults.setObject(data, forKey: "data")
var storedQuestionsAsked = defaults.objectForKey("questionsAsked") as? [String] ?? [String]()
var storedData = defaults.objectForKey("data") as? [String] ?? [String]()
}
The array(s) are based in my Modal, and the appending is occurring by appending that array in the ViewController of that Modal
I tried just calling a function like this, but this is just calling an empty array because its never being re-saved to the NSUserDefaults:
func updateQuestionsAsked(questionAsked: String, answerGiven: String) {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject([String](), forKey: "questionsAsked")
defaults.setObject([String](), forKey: "data")
var storedQuestionsAsked = defaults.objectForKey("questionsAsked") as? [String] ?? [String]()
var storedData = defaults.objectForKey("data") as? [String] ?? [String]()
storedData.append(questionAsked)
storedQuestionsAsked.append(answerGiven)
NSUserDefaults.standardUserDefaults().synchronize()
}
Is there some kind of synchronization thing I'm missing? I'm sure this is super simple but I'm just spacing out on what to do. Thanks!
YOu are setting empty data for keys "questionsAsked" & "data",
func updateQuestionsAsked(questionAsked: String, answerGiven: String) {
let defaults = NSUserDefaults.standardUserDefaults()
//remove this
//defaults.setObject([String](), forKey: "questionsAsked")
//defaults.setObject([String](), forKey: "data")
var storedQuestionsAsked = defaults.objectForKey("questionsAsked") as? [String] ?? [String]()
var storedData = defaults.objectForKey("data") as? [String] ?? [String]()
storedData.append(questionAsked)
storedQuestionsAsked.append(answerGiven)
// then update whats in the `NSUserDefault`
defaults.setObject(questionsAsked, forKey: "questionsAsked")
defaults.setObject(data, forKey: "data")
// call this after you update
defaults.synchronize()
}
Another is maybe you failed to set object here...
func storeData() {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(questionsAsked, forKey: "questionsAsked")
defaults.setObject(data, forKey: "data")
// call this after setting Objects
//--
defaults.synchronize()
//--
...
}