Save string to the NSUserDefaults?
NSString *valueToSave = @"someValue";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"preferenceName"];
[[NSUserDefaults standardUserDefaults] synchronize];
to get it back later
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:@"preferenceName"];
Store [String] in NSUserDefaults
The following code should help you resolve your problem:
import UIKit
class ViewController: UIViewController {
var food: [String] {
get {
if let returnValue = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [String] {
return returnValue
} else {
return ["muesli", "banana"] //Default value
}
}
set {
NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "food")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
override func viewDidLoad() {
super.viewDidLoad()
print(food) // prints: ["muesli", "banana"] (at first launch)
food = ["cake"]
print(food) // prints: ["cake"]
food += ["spaghetti"]
print(food) // prints: ["cake", "spaghetti"]
food = []
print(food) // prints: []
NSUserDefaults.standardUserDefaults().setObject(nil, forKey: "food")
print(food) // prints: ["muesli", "banana"]
}
}
However, with the previous code, if you set food = []
, you will have a problem as food
won't return ["muesli", "banana"]
. In order to avoid this, you may prefer the following code:
import UIKit
class ViewController: UIViewController {
var food: [String] {
get {
if let returnValue = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [String] {
return returnValue == [] ? ["muesli", "banana"] : returnValue
} else {
return ["muesli", "banana"] //Default value
}
}
set {
NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "food")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
override func viewDidLoad() {
super.viewDidLoad()
print(food) // prints: ["muesli", "banana"] (at first launch)
food = ["cake"]
print(food) // prints: ["cake"]
food += ["spaghetti"]
print(food) // prints: ["cake", "spaghetti"]
food = []
print(food) // prints: ["muesli", "banana"]
NSUserDefaults.standardUserDefaults().setObject(nil, forKey: "food")
print(food) // prints: ["muesli", "banana"]
}
}
Swift NSUserDefaults setString:forKey:?
The reason that setObject can be used to apply a string is found in the discussion of the reference:
Since Swift String is bridged to NSString, the usage of setObject is valid. However as the other types mentioned are not accepted in NSUserDefaults using the setObject setter; they have their own convenience setters.
Notwithstanding this, almost anything one can think of can be serialized and placed into NSUserDefaults using setObject with an NSData argument (as noted elsewhere on SO).
How to use store and use an NSMutableAttributedString in NSUserDefaults
You have to convert your NSMutableAttributedString
into NSData
then you store it in NSUserDefaults
.
// Convert into NSData
let data = NSKeyedArchiver.archivedDataWithRootObject(distanceMutableAttributedString)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "yourStringIntoData")
// Convert your NSData to NSMutableAttributedString
let yourStringInData = NSUserDefaults.standardUserDefaults().objectForKey("yourStringIntoData") as? NSData
let newStr = NSKeyedUnarchiver.unarchiveObjectWithData(yourStringInData!) as? NSMutableAttributedString
// Assign it to your textView
textView.attributedText = newStr
Converting [NSURL] into [String] for NSUserDefaults?
Using NSData
You can convert each NSURL
to NSData
in order to save it
func save(urls: [NSURL]) {
let urlsData = urls.map { $0.dataRepresentation }
NSUserDefaults.standardUserDefaults().setObject(urlsData, forKey: "urlsData")
}
Later on you can retrieve the NSData
array and convert it back to [NSURL]
func load() -> [NSURL]? {
let retrievedData = NSUserDefaults.standardUserDefaults().arrayForKey("urlsData") as? [NSData]
return retrievedData?.map { NSURL(dataRepresentation: $0, relativeToURL: nil) }
}
Using String
Alternatively you can save the urls as String(s)
func save(urls: [NSURL]) {
let urlsData = urls.map { $0.absoluteString }
NSUserDefaults.standardUserDefaults().setObject(urlsData, forKey: "urlsData")
}
func load() -> [NSURL?]? {
let retrievedData = NSUserDefaults.standardUserDefaults().arrayForKey("urlsData") as? [String]
return retrievedData?.map { NSURL(string: $0) }
}
As discussed in the comments below, if data is written to NSUserDefaults
exclusively with the save
function, we know that every element of the array is a String
representing a valid NSURL
.
So we can change the return type of load
from [NSURL?]?
to [NSURL]?
using this alternate version of load
.
func load() -> [NSURL]? {
let retrievedData = NSUserDefaults.standardUserDefaults().arrayForKey("urlsData") as? [String]
return retrievedData?.flatMap { NSURL(string: $0) }
}
NSUserDefaults returns swift array [String] instead of Set String
Short answer : No
NSUserDefaults
cannot store sets. It's documented that way and it's because of the limitations of the format used to store the data on disk.
If saving a set works for you and automatically converts it to an array, you're actually lucky as I don't think this is a documented behavior and it should just throw an error.
EDIT : It doesn't work and you should not try it.
The best practice is to convert it to an array before saving and convert it back to a set after retrieving. You could also write a category on NSUserDefaults
that does that automatically. Here is an example with objective-C :
//
// NSUserDefaults+SetAdditions.h
//
#import
@interface NSUserDefaults (SetAdditions)
- (NSSet *)setForKey:(NSString *)defaultName;
- (void)setSet:(NSSet *)set forKey:(NSString *)defaultName;
@end
//
// NSUserDefaults+SetAdditions.m
//
#import "NSUserDefaults+SetAdditions.h"
@implementation NSUserDefaults (SetAdditions)
- (NSSet *)setForKey:(NSString *)defaultName
{
NSArray *array = [self arrayForKey:defaultName];
if (array) {
return [NSSet setWithArray:array];
} else {
return nil;
}
}
- (void)setSet:(NSSet *)set forKey:(NSString *)defaultName
{
if (set) {
[self setObject:[set allObjects] forKey:defaultName];
} else {
[self setObject:nil forKey:defaultName];
}
}
@end
How can I use UserDefaults in Swift?
ref: NSUserdefault objectTypes
Swift 3 and above
Store
UserDefaults.standard.set(true, forKey: "Key") //Bool
UserDefaults.standard.set(1, forKey: "Key") //Integer
UserDefaults.standard.set("TEST", forKey: "Key") //setObject
Retrieve
UserDefaults.standard.bool(forKey: "Key")
UserDefaults.standard.integer(forKey: "Key")
UserDefaults.standard.string(forKey: "Key")
Remove
UserDefaults.standard.removeObject(forKey: "Key")
Remove all Keys
if let appDomain = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: appDomain)
}
Swift 2 and below
Store
NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "yourkey")
NSUserDefaults.standardUserDefaults().synchronize()
Retrieve
var returnValue: [NSString]? = NSUserDefaults.standardUserDefaults().objectForKey("yourkey") as? [NSString]
Remove
NSUserDefaults.standardUserDefaults().removeObjectForKey("yourkey")
Register
registerDefaults: adds the registrationDictionary to the last item in every search list. This means that after NSUserDefaults has looked for a value in every other valid location, it will look in registered defaults, making them useful as a "fallback" value. Registered defaults are never stored between runs of an application, and are visible only to the application that registers them.
Default values from Defaults Configuration Files will automatically be registered.
for example detect the app from launch , create the struct for save launch
struct DetectLaunch {
static let keyforLaunch = "validateFirstlunch"
static var isFirst: Bool {
get {
return UserDefaults.standard.bool(forKey: keyforLaunch)
}
set {
UserDefaults.standard.set(newValue, forKey: keyforLaunch)
}
}
}
Register default values on app launch:
UserDefaults.standard.register(defaults: [
DetectLaunch.isFirst: true
])
remove the value on app termination:
func applicationWillTerminate(_ application: UIApplication) {
DetectLaunch.isFirst = false
}
and check the condition as
if DetectLaunch.isFirst {
// app launched from first
}
UserDefaults suite name
another one property suite name, mostly its used for App Groups concept, the example scenario I taken from here :
The use case is that I want to separate my UserDefaults (different business logic may require Userdefaults to be grouped separately) by an identifier just like Android's SharedPreferences. For example, when a user in my app clicks on logout button, I would want to clear his account related defaults but not location of the the device.
let user = UserDefaults(suiteName:"User")
use of userDefaults synchronize, the detail info has added in the duplicate answer.
Objective C - Saving a variable inside NSUserDefaults
You have missed sync call.Apply this to save it.
if (button.selected)
{
[button setSelected:YES];
[[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithBool:YES] forKey:@"buttonSelected"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
to get it back later
NSNumber* savedValue = [[NSUserDefaults standardUserDefaults]
objectForKey:@"buttonSelected"];
This is if you want to store only the value.
If you want to store your custom object look at this link
How to store custom objects in NSUserDefaults
Save & Format String using NSUserDefaults
Solution found.
Save the new text for example here
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
let data = NSKeyedArchiver.archivedDataWithRootObject(textView.attributedText)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "sawedString")
textView.resignFirstResponder()
}
Upload saved text when opening
override func viewDidLoad() {
super.viewDidLoad()
if let myStringData = NSUserDefaults.standardUserDefaults().objectForKey("sawedString") as? NSData {
let savedString = NSKeyedUnarchiver.unarchiveObjectWithData(myStringData) as? NSAttributedString
textView.attributedText = savedString
}
}
Use the NSAttributedString instead of the NSMutableAttributedString!
Related Topics
How to Resize Uiimageview Based on Uiimage's Size/Ratio in Swift 3
Swift Apply .Uppercasestring to Only the First Letter of a String
Wait Until Multiple Networking Requests Have All Executed - Including Their Completion Blocks
Adding a Uilabel to a Uitoolbar
How to Fix "No Valid 'Aps-Environment' Entitlement String Found for Application" in Xcode 4.3
Uiscrollview: Paging Horizontally, Scrolling Vertically
How to Check If Uilabel Is Truncated
How to Load a Xib File in a Uiview
How to Obtain a Dynamic Table View Section Header Height Using Auto Layout
How to Achieve a "Clock Wipe"/ Radial Wipe Effect in iOS
Combine Framework: How to Process Each Element of Array Asynchronously Before Proceeding
Dynamic Height Issue for Uitableview Cells (Swift)
How to Get Uikeyboard Size with iOS
How to Insert the Uitextview into Uialertview in iOS
iOS App Freezes on Pushviewcontroller