I am trying to save data to UserDefaults using an UIAlertController , but the code fails to retrieve the data.
Retrieve the Data
func displayCreatedPhrases(){
phrases = uDefaults.stringArray(forKey: "createdPhrases") ?? [String]()
print(phrases)
}
Setting the Data
self.uDefaults.set(textfield.text, forKey: "createdPhrases")
self.uDefaults.synchronize()
print("Saved the data!")
self.phraseTableView.reloadData()
You are setting the string as a value for key 'createdPhrases' and then asking uDefaults to return an array of string?
func displayCreatedPhrases() {
phrases = uDefaults.value(forKey: "createdPhrases") as? String
print(phrases)
}
The above code should work for you.
Also no need to use below line (Link to UserDefaults synchronize)
self.uDefaults.synchronize()
Reason:
textfield.text is of type String? and not [String]. In your code, you're saving the data as a String value and retrieving it as an [String] value. That's the reason, retrieving the data doesn't work.
Solution:
func displayCreatedPhrases(){
phrases = uDefaults.string(forKey: "createdPhrases") ?? ""
print(phrases)
}
Also, phrases must be of type String.
Related
I am tracking a user's preferences in my iOS app using UserDefaults -- when a user selects a table cell, it adds the cell's text to my key. That part works.
Now, I want to allow the user to remove the matching key value from the key when a row is selected. If a cell says "Episode 1", it should remove the value from UserDefaults.
From the documentation, there's an instance method for removeObject. Here's what I wrote:
let defaults = UserDefaults.standard
var myarray = defaults.stringArray(forKey: "SavedStringArray") ?? [String]()
if let datastring = TableData[indexPath.row] as? String {
if !myarray.contains(datastring) {
myarray.append(datastring)
defaults.removeObject(myarray, forKey: "SavedStringArray")
defaults.synchronize()
}
This returns an error for Extra argument in call -- I assume it means myarray, but if I can't add that argument, how can I tell it to remove only one value (stored in myarray)?
If I print the UserDefaults.standard, it will return a list of stored episode values like `["First Episode", "Second Episode", "Third Episode"]
Any idea how I can remove Third Episode when that cell is clicked here?
I have following code which will work for you.
if myarray.contains(datastring) {
myarray.remove(at: myarray.index(of: datastring)!)
} else {
myarray.append(datastring)
}
defaults.set(myarray, forKey: "SavedStringArray")
This code will remove element from array and set array again in User defaults for same key, So it will replace you array with new array.
You can add if string is not present or remove the string if it is present. And then update the array.
Then set that array for the key.
if !myarray.contains(datastring) {
myarray.append(datastring)
} else {
myarray = myarray.filter{$0 != datastring}
}
defaults.set(myarray, forKey: "SavedStringArray")
You can try This logic for array of type String i.e. [String]
var arrStr:[String] = ["Cat","Rat","Mouse"]
print(arrStr)
let datastring = "Rat"
if !arrStr.contains(datastring) {
arrStr.append(datastring)
} else {
arrStr.remove(at: arrStr.index(of: datastring)!)
}
print(arrStr)
UserDefaults.standard.set(arrStr, forKey: "SavedStringArray")
UserDefaults.standard.synchronize()
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'm trying to save key value in the NSUserDefaults but is not been save. Here is my code:
func saveData() {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject("blablabla", forKey:"data")
userDefaults.synchronize()
}
Any of you knows why this data is not been save?
I'll really appreciate your help.
Swift 2.x:
According with Apple sources:
public func objectForKey(defaultName: String) -> AnyObject?
to retrieve your value you could use:
if let value = userDefaults.objectForKey("data") {
// do whatever you want with your value
// P.S. value could be numeric,string,..
}
I think you are doing it wrong, try like this:
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject("blablabla", forKey:"data")
let defaults = NSUserDefaults.standardUserDefaults()
if let name = defaults.stringForKey("data") {
print(name)
}
You won't be able to access a string with dictionaryForKey because string is not a dictionary value type. Let me know if you need any further help.
You won't be able to access a string with 'dictionaryForKey' because a string is not a dictionary value type. You'll need to use:
if let savedString = userDefaults.stringForKey("data") {
print(savedString)
}
If you have any further questions feel free to let me know :)
How to delete data from NSUserDefaults? There is quite a few answers how to do it in Objective C, but how about Swift?
So I tried this:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.removeObjectForKey("myKey")
Didn't work. Maybe what I really want to delete is not NSUserDefaults?
This is how I save data:
class MySavedData: NSObject, NSCoding {
var image: String
init(name: String, image: String) {
self.image = image
}
required init(coder aDecoder: NSCoder) {
image = aDecoder.decodeObjectForKey("image") as! String
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(image, forKey: "image")
}
}
class ViewController: <...> {
var myData = [MySavedData]() //Later myData gets modified and then function save() is called
func save() {
let savedData = NSKeyedArchiver.archivedDataWithRootObject(myData)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(savedData, forKey: "myKey")
}
}
EDIT: Just to clear some things - data that is being saved is small (not even close to 100kb)
And maybe I am saving data not to NSUserDefaults (I am new to programming), so here is how I get it (load):
let defaults = NSUserDefaults.standardUserDefaults()
if let savedData = defaults.objectForKey("myData") as? NSData {
myData = NSKeyedUnarchiver.unarchiveObjectWithData(savedData) as! [UserLogin]
}
removeObjectForKey is the right way to go.
This will remove the value for the selected key. The following code sets a string value for a key in NSUserDefaults, prints it and then uses removeObjectForKey to remove and print the key value again. After removeObjectForKey the value is nil.
let prefs = NSUserDefaults.standardUserDefaults()
var keyValue = prefs.stringForKey("TESTKEY")
print("Key Value not set \(keyValue)")
let strHello = "HELLO WORLD"
prefs.setObject(strHello, forKey: "TESTKEY")
keyValue = prefs.stringForKey("TESTKEY")
print("Key Value \(keyValue)")
prefs.removeObjectForKey("TESTKEY")
keyValue = prefs.stringForKey("TESTKEY")
print("Key Value after remove \(keyValue)")
Returns:
Key Value not set nil
Key Value Optional("HELLO WORLD")
Key Value after remove nil
Update Swift 3:
let prefs = UserDefaults.standard
keyValue = prefs.string(forKey:"TESTKEY")
prefs.removeObject(forKey:"TESTKEY")
The code you have written will work fine, but NSUserDefaults synchronise at certain time interval.
As you want that should reflect in NSUserDefaults immediately ,so u need to write synchronise
let defaults = NSUserDefaults.standardUserDefaults()
defaults.removeObjectForKey("myKey")
defaults.synchronize()
Try This
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(NSBundle.mainBundle().bundleIdentifier!)
for Swift 3
UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
But this will clear all values from NSUserDefaults.careful while using.
Removing UserDefaults for key in swift 3, based upon the top answer, just slightly different syntax:
UserDefaults.standard.removeObject(forKey: "doesContractExist")
Swift 4.x Remove all key in UserDefaults
let defaults = UserDefaults.standard
let dictionary = defaults.dictionaryRepresentation()
dictionary.keys.forEach
{ key in defaults.removeObject(forKey: key)
}
Use following for loop:
for key in NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys {
NSUserDefaults.standardUserDefaults().removeObjectForKey(key.description)
}
I would go for a solution which setting the value to nil for a key.
Swift 3
UserDefaults.standard.set(nil, forKey: "key")
Swift 2.x
NSUserDefaults.standardUserDefaults().setValue(nil, forKey: "key")
NOTE: that is a clear and straight statement, but bear in mind there is a limit to store information in NSUserDefaults, it is definitely not the right place to store large binary files (like e.g. images) – for that there is a Documents folder. however it is not defined how big the var image: String which you encode/decode.
To nuke all UserDefaults keys, you can use the following code in Swift 3.x:
UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
In Swift 5.0, iOS 15 below single line of code is enough.
UserDefaults.standard.dictionaryRepresentation().keys.forEach(defaults.removeObject(forKey:))
Or try this
if let appDomain = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: appDomain)
}
func remove_pref(remove_key : String){
UserDefaults.standard.removeObject(forKey: remove_key)
UserDefaults.standard.synchronize()
}
Update code for Swift :
Used below line of code to Delete key values for NSUserDefaults in Swift
UserDefaults.standard.setValue(nil, forKey: "YouEnterKey")
I can't get a value out of this computed property (userList)...is my init set up correctly? I'm trying to build a list that will populate the rows in my table view. (*Edit: I've edited my question with a saveData function, but "cannot invoke setObject" with an argument list of type ([String : User], forKey: String)" –
import Foundation
class DataManager {
static let sharedInstance = DataManager()
var users = [String : User]()
init() {
let userDefaults = NSUserDefaults.standardUserDefaults()
if let var userFromDefaults = userDefaults.objectForKey("userKey") as? [String : User] {
users = userFromDefaults
}
else {
// add default values later
}
}
func saveData() {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(users, forKey: "userKey")
}
var userList: [String] {
var list: [String] = []
for name in users.keys {
list.append(name)
}
list.sort(<)
return list
}
My viewcontroller:
import UIKit
class NameViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var users: [String] = DataManager.sharedInstance.userList
User Struct with a method to convert into json:
import Foundation
struct User {
var name = ""
var stores: [Store] = []
init?(json: [String: AnyObject]) {
if let name = json["name"] as? String,
storesJSON = json["stores"] as? [[String: AnyObject]]
{
self.name = name
self.stores = storesJSON.map { Store(json: $0)! }
} else {
return nil
}
}
init() { }
func toJSON() -> [String: AnyObject] {
return [
"name": name,
"stores": stores.map { $0.toJSON() }
]
}
}
You can grab all keys/Values using (from apple documentation)
dictionaryRepresentation() Returns a dictionary that contains a union
of all key-value pairs in the domains in the search list.
Using this you can loop all the elements in the dictionary
for element in NSUserDefaults.standardUserDefaults().dictionaryRepresentation() {
println(element)
//Do what you need to do here
}
You can also retrieve just the keys:
println(NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys.array);
or just the values
println(NSUserDefaults.standardUserDefaults().dictionaryRepresentation().values.array);
As Matt pointed out in his comment, you need to save contents to NSUserDefaults before you can read them.
Something else that will prevent your code from working:
NSUserDefaults will only save "property list" objects (NSString, NSData, NSDate, NSNumber, NSArray, or NSDictionary objects or their Swift equivalents.)
If you try to save anything else, or a collection containing anything but those data types, the save fails and you get nil when you try to read it back. Your code shows you trying to save a dictionary where the value for each key is an object of type "User". That's going to fail since "User" is not one of the short list of "property list" object types.
This is not a good user of NSUserDefaults, which is meant to store preferences and other small bits of data between app launches. See the documentation on NSUserDefaults.
You should be managing this dictionary of users in memory when you are displaying data, and if you want to persist it to disk between app launches you should use CoreData or make your User class conform to NSCoding and read/write it with archiving. Here's a nice tutorial.