How to retrieve string from UserDefaults in Swift? - ios

I have a textField for the user to input their name.
#IBAction func nameTextField(sender: AnyObject) {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("\(nameTextField)", forKey: "userNameKey")
}
Then I recall the inputted name in ViewDidLoad with:
NSUserDefaults.standardUserDefaults().stringForKey("userNameKey")
nameLabel.text = "userNameKey"
What am I doing wrong? Result is simply "userNameKey" every time. I'm new to this, thanks!

You just have to assign the result returned by nsuserdefaults method to your nameLabel.text. Besides that stringForKey returns an optional so I recommend using the nil coalescing operator to return an empty string instead of nil to prevent a crash if you try to load it before assigning any value to the key.
func string(forKey defaultName: String) -> String?
Return Value For string values, the string associated with the
specified key. For number values, the string value of the number.
Returns nil if the default does not exist or is not a string or number
value.
Special Considerations
The returned string is immutable, even if the value you originally set was a mutable string.
You have to as follow:
UserDefaults.standard.set("textToSave", forKey: "userNameKey")
nameLabel.text = UserDefaults.standard.string(forKey: "userNameKey") ?? ""

What you need to do is:
#IBAction func nameTextField(sender: AnyObject) {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.set(yourTextField.text, forKey: "userNameKey")
}
And later in the viewDidLoad:
let defaults = NSUserDefaults.standardUserDefaults()
let yourValue = defaults.string(forKey: "userNameKey")
nameLabel.text = yourValue

Related

Unable to get String value from UserDefaults

Unable to get the string value stored in UserDefaults
var videoString = String()
In view did load
videoString = "http://site4brandz.com/cphp/26/uploads/oggy.mp4"
UserDefaults.standard.set(videoString as String, forKey: CurrentURL)
UserDefaults.standard.synchronize()
print("\(UserDefaults.standard.object(forKey: CurrentURL))")
It's printing as follows:
Optional(http://site4brandz.com/cphp/26/uploads/oggy.mp4)
When I go back and checking the same string like
if (UserDefaults.standard.value(forKey: CurrentURL) != nil) {
print("\(UserDefaults.standard.value(forKey: CurrentURL))")
let runningSrtring = UserDefaults.standard.value(forKey: CurrentURL)!
}
But now it's printing as Optional(4.067826) where did I made a mistake?
In Swift3
How about use UserDefaults.standard.string(forKey: CurrentURL)!
instead UserDefaults.standard.value(forKey: CurrentURL)!
Change your UserDefaults set code:
from:
UserDefaults.standard.set(videoString as String, forKey: CurrentURL)
to
if videoString {
UserDefaults.standard.set(videoString!, forKey: CurrentURL)
}
and check the different!
in Swift 2.3
you can set value string in UserDefaults
NSUserDefaults.standardUserDefaults().setObject(videoString, forKey: CurrentURL)
By get the value from
if let string = NSUserDefaults.standardUserDefaults().stringforKey(CurrentURL) {
}
In Swift 3
you can set value string in UserDefaults
UserDefaults.standard.set(videoString, forKey: CurrentURL)
By get the value from UserDefaults
if let string = UserDefaults.standard.string(forKey: CurrentURL) {
}
Make sure your key "CurrentURL" have same Value
Try it with Swift3:
extension UserDefaults {
func setValue(value: String, key: String) {
set(value, forKey: key)
synchronize()
}
func getValue(key: String) -> String {
return string(forKey: key)
}
}
Usage:
let videoString: String = "http://site4brandz.com/cphp/26/uploads/oggy.mp4"
UserDefaults.standard.setValue(value: videoString, key: CurrentURL)
and check it:
print(UserDefaults.standard.getValue(key: CurrentURL))
Notice that i am using key as a String. Change key's type to CurrentURL type as you expect (e.g: URL Type, ...)

Delete key values for NSUserDefaults in Swift

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

Adding object to enum gives me error

I have an enum, and a variable that points to a certain object in the enum.
enum Collection {
case First, Second, Third, Fourth
}
var myCollection = Collection.Second
I want to pass myCollection to the NSUserDefaults. Here's what I did: (I hope viewDidLoad is the right place to put it.)
override func viewDidLoad() {
super.viewDidLoad()
// Save the sort by NSUserDefualt
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(self.myCollection, forKey: "myKey")
}
At the last line, I get the following error:
Cannot invoke 'setObject' with an argument list of type '(myViewController.Collection, forKey: String)'
What am I doing wrong, and how can I fix it?
Update
Does this make sense?
let defaults = NSUserDefaults.standardUserDefaults()
let defaultRawValue = defaults.integerForKey("myKey")
if defaultRawValue != nil {
defaults.setInteger(myCollection.rawValue, forKey: "myKey")
} else {
defaults.setInteger(1, forKey: "myKey")
}
myCollection = Collection(rawValue: defaultRawValue)!
NSUserDefaults can only take PropertyList: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PropertyLists/AboutPropertyLists/AboutPropertyLists.html
Try
enum Collection:Int{
case First=1, Second, Third, Fourth
}
var myCollection = Collection.Second
override func viewDidLoad() {
super.viewDidLoad()
let defaults = NSUserDefaults.standardUserDefaults()
let defaultRawValue = defaults.integerForKey("myKey")
if defaultRawValue > 0{
myCollection = Collection(rawValue: defaultRawValue)!
}
else
{
defaults.setInteger(1, forKey: "myKey")
myCollection = Collection(rawValue: 1)
}
}
The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary.
So, if you want to store your enum in NSUserDefaults, you use rawValue for your enum. Here I use String, like this:
enum Collection: String {
case First = "First"
case Second = "Second"
case Third = "Third"
case Fourth = "Fourth"
}
//create myCollection
var myCollection = Collection(rawValue: "Second")
And store it:
override func viewDidLoad() {
super.viewDidLoad()
// Save the sort by NSUserDefualt
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(self.myCollection.rawValue, forKey: "myKey")
}

Save variable after my app closes (swift)

I'm trying to save a variable in Xcode so that it saves even after the app has closed, how ever when I access it I do it from a several different classes and files, and I change the value of the variable when I access it. Therefore similar threads do not completely apply, the value to be stored is a string and here is the code I have up until now:
var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(Token, forKey: "") as! String
I believe this is the correct format, but I don't know how to call it to change it because when I try I get an error message saying expected declaration.
Anyway any help would be very much appreciated.
First of all you have to specify an unique key to store the variable (in the example MyKey ).
In AppDelegate > applicationDidFinishLaunching register the key with a default value.
The benefit is you can use a non-optional variable and you have a defined default value.
let defaults = UserDefaults.standard
let defaultValue = ["MyKey" : ""]
defaults.register(defaults: defaultValue)
Now you can from everywhere read the value for the key
let defaults = UserDefaults.standard
let token = defaults.string(forKey: "MyKey")
and save it
let defaults = UserDefaults.standard
defaults.set(token, forKey: "MyKey")
Swift 3
(thanks to vadian's answer)
In AppDelegate > applicationDidFinishLaunching :
let defaults = UserDefaults.standard
let defaultValue = ["myKey" : ""]
defaults.register(defaults: defaultValue)
to save a key:
let defaults = UserDefaults.standard
defaults.set("someVariableOrString", forKey: "myKey")
defaults.synchronize()
to read a key:
let defaults = UserDefaults.standard
let token = defaults.string(forKey: "myKey")
Let's say you have a string variable called token
To save/update the stored value on the device:
NSUserDefaults.standardUserDefaults().setObject(token, forKey: "mytoken")
NSUserDefaults.standardUserDefaults().synchronize()
In the code above I made sure to give the key a value ("mytoken"). This is so that we later can find it.
To read the stored value from the device:
let token = NSUserDefaults.standardUserDefaults().objectForKey("mytoken") as? String
Since the method objectForKey returns an optional AnyObject, I'll make sure to cast it to an optional String (optional meaning that it's either nil or has a value).
Add default.synchronize() after setting value.

Swift load from userDefaults into UItextfield.text

Im trying to retrieve a Int value from a userdefault and show it in a input field, but I keep getting the fatal error: unexpectedly found nil while unwrapping an Optional value, it must be a wrong placed ! or ? somewhere in this code. I have used hours now :-(
func LoadFromDefaultDistances(){
if let v = defaults.objectForKey("DriverMin") as? NSInteger {
inputDriverMin.text = String(defaults.objectForKey("DriverMin") as! NSInteger)
}
}
Use this code to save the value.
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Your in value", forKey: "myIntValue")
defaults.synchronize()
And use this code to get it back.
let defaults = NSUserDefaults.standardUserDefaults()
if let theInt = defaults.stringForKey("myIntValue")
{
inputDriverMin.text = theInt
}

Resources