How do I set and load NSUserDefaults in AppDelegate - ios

In didFinishLaunchingWithOptions I have:
let defaults = NSUserDefaults.standardUserDefaults()
if let name = defaults.stringForKey("userNameKey") {
println(name)
}
In the applicationWillTerminate I have:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Coding Explorer", forKey: "userNameKey")
But upon application load(which i've closed and reopened several times on the iphone simulator), it does not print. Any clue why?

it could be better to use debugger to see whether or not your code invoke the following method applicationWillTerminate
Before we read or write data from NSUserDefaults, we must first get a reference to the NSUserDefaults class.
let prefs = NSUserDefaults.standardUserDefaults()
For further information:
Once we have the reference saved to a constant, we can write data to it. You will be defining both the value and the key name to store the data.
prefs.setValue("Berlin", forKey: "userCity")
//This code saves the value "Berlin" to a key named "userCity".
More information could be found in the following link: http://www.myswiftjourney.me/2014/10/01/simple-persistent-storage-using-nsuserdefaults/

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Coding Explorer", forKey: "userNameKey")
defaults.synchronize()

you forgot to synchronize after writing to userdefaults...
i think this is for swift !?
defaults.synchronize()
in objective-c it s
[defaults synchronize];

Related

UserDefaults removeObjectForKey not working?

I have set some value in user default in my app at beginning. Then those values may get overridden by the user and i want to delete those settings.
When i try to delete all default a few key-value removed but a few keys are not removed immediately. When i kill app & again back to app it work as deleted. As i expected it should work immediately after its delete key
Here is my code in swift 3.2 for set default value
let sharedUserDefaultsWithExtension = UserDefaults(suiteName: "GROUP_IDENTIFIER")
sharedUserDefaultsWithExtension?.setValue(newValue, forKey: "My_Key")
sharedUserDefaultsWithExtension?.synchronize()
Code for delete all user default value
let sharedUserDefaultsWithExtension = UserDefaults(suiteName: "GROUP_IDENTIFIER")
for key in (sharedUserDefaultsWithExtension?.dictionaryRepresentation().keys)! {
sharedUserDefaultsWithExtension?.removeObject(forKey: key)
}
sharedUserDefaultsWithExtension?.synchronize()
Any idea?
If you want to delete all data from userdefault then use:
let bundleIdentifier = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: bundleIdentifier)
And for set the data in user default:
UserDefaults.standard.setValue("jogendar", forKey: "My_Key")
And in your way, you need to synchronize the data just after remove but don't try synchronize() as mention in doc https://developer.apple.com/documentation/foundation/userdefaults/1414005-synchronize
synchronize() :- Waits for any pending asynchronous updates to the defaults database and returns; this method is unnecessary and shouldn't be used.
let sharedUserDefaultsWithExtension = UserDefaults(suiteName: "GROUP_IDENTIFIER")
for key in (sharedUserDefaultsWithExtension?.dictionaryRepresentation().keys)! {
sharedUserDefaultsWithExtension?.removeObject(forKey: key)
sharedUserDefaultsWithExtension?.synchronize()
}

Saving data (numbers) in an iOS app?

I'm learning application development working on a quiz game. I'd like to add statistics to the game. For example, the average score since the app has been downloaded. How can I store the scores on the device in order to reuse them after the app has been closed?
You should take a look at UserDefault. It's basically a dictionary that persists until the user uninstalls your app. I like to write a wrapper around it to get strong typing and ease of reference:
struct Preferences {
static func registerDefaults() {
UserDefaults.standard.register(defaults: [kAverageScore: 0])
}
// Define your key as a constant so you don't have to repeat a string literal everywhere
private static let kAverageScore = "averageScore"
static var averageScore: Double {
get { return UserDefaults.standard.double(forKey: kAverageScore) }
set { UserDefaults.standard.set(newValue, forKey: kAverageScore) }
}
}
Here's how to use it: before you call it for the first time in your app, you must register the defaults. These are the values that your app ships with. On iOS, it only really matters for the very first time the user launches your app. On OS X, do this every time your app starts because the user can delete the app's preferences from ~/Library/Application Support.
// You usually do this in viewDidLoad
Preferences.registerDefaults()
From then on, getting and setting the property is easy:
let averageScore = Preferences.averageScore
Preferences.averageScore = 5.5
You should take a look at UserDefaults
Example
let defaults = UserDefaults.standard
defaults.set(25, forKey: "Age")
defaults.set(true, forKey: "UseTouchID")
defaults.set(Double.pi, forKey: "Pi")
To read values back
let age = defaults.integer(forKey: "Age")
let useTouchID = defaults.bool(forKey: "UseTouchID")
let pi = defaults.double(forKey: "Pi")
UserDefaults

Shared UserDefaults between app and extension not working correctly

So I've been looking around and following all the steps to setup shared UserDefaults correctly but I should be missing something.
I have App Groups capability activated on both my app and my extension. Both use the same suite name ("group.TestSharedPreferences") and I write this way:
struct Preferences {
static let shared = UserDefaults(suiteName: "group.TestSharedPreferences")!
}
On viewDidLoad:
Preferences.shared.set(1, forKey: "INT")
And to read:
Preferences.shared.integer(forKey: "INT") // Returns 1 in Container App
Preferences.shared.integer(forKey: "INT") // Returns 0 in Today Extension
Even using synchronize() just after setting "INT", the value retrieved in the extension is not the one saved in the container App. Any ideas on what might I be missing? Thank you!
I would recommend to dig down step by step here.
First, make sure that both the main app and the widget extension have app group capability enabled and use the same and activated (the checkmark must be set) app group name:
Main App:
Today Widget Extension:
Then make a simple test with direct set/get access. In your main app's AppDelegate.didFinishLaunchingWithOptions method (change the app group name and the keys to your needs):
if let userDefaults = UserDefaults(suiteName: "group.de.zisoft.GPS-Track") {
userDefaults.set("test 1" as AnyObject, forKey: "key1")
userDefaults.set("test 2" as AnyObject, forKey: "key2")
userDefaults.synchronize()
}
In your Today Widget Extension's ViewController:
if let userDefaults = UserDefaults(suiteName: "group.de.zisoft.GPS-Track") {
let value1 = userDefaults.string(forKey: "key1")
let value2 = userDefaults.string(forKey: "key2")
...
}
If this works, the problem must be related in your Preferences singleton.

Why doesn't NSUserDefaults work between my app & share extension?

I have an iOS app with a share extension. I am trying to share data between them using NSUserDefaults and App Groups but, while I can write into the NSUD object, read it, and synchronize() without error, reading in the extension always results in nil.
I have an app group, the literal string "group.net.foo.bar" for which both the app & extension have configured under Capabilities -> App Groups. This string is in a constants struct in my app:
struct Forum {
static let APP_GROUP = "group.net.foo.bar"
static let AUTH_KEY = "AUTH_KEY"
}
In the main app I create a UserDefaults object and write to it:
fileprivate lazy var userDefaults: UserDefaults = {
let defaults = UserDefaults()
defaults.addSuite(named: Forum.APP_GROUP)
return defaults
}()
// later
userDefaults.set(apiKey, forKey: Forum.AUTH_KEY)
userDefaults.synchronize()
Creating a new NSUD object after that synchronize() and retrieving the AUTH_KEY works. In the extension, I create an NSUD and try to retrieve the value, to no avail:
private lazy var userDefaults: UserDefaults = {
let defaults = UserDefaults()
defaults.addSuite(named: Forum.APP_GROUP)
return defaults
}()
// later
private func getApiKey() -> String? {
return userDefaults.string(forKey: Forum.AUTH_KEY)
}
// returns nil
In all of my reading of the Apple docs and depressingly-similar questions here on Stack Overflow I can't divine what I've done incorrectly.
Xcode Version 8.0 (8A218a), also tested with Xcode 8.1 Beta 2. Same behavior on simulator andy my iPhone 6s running iOS 10.
Not sure if defaults.addSuite(named: ...) does the same as UserDefaults(suiteName: ...). In my app I use appGroups this way and it works as expected:
// write
if let userDefaults = UserDefaults(suiteName: appGroupName) {
userDefaults.set("---" as AnyObject, forKey: "distance")
userDefaults.set("---" as AnyObject, forKey: "altitude")
...
userDefaults.synchronize()
}
// read
if let userDefaults = UserDefaults(suiteName: appGroupName) {
self.distanceLabel.text = userDefaults.string(forKey: "distance")
self.altitudeLabel.text = userDefaults.string(forKey: "altitude")
}
if you suffer this problem when you try to save data to extension APP by using userDefault,maybe you had written this code : [[NSUserDefaults standardUserDefaults] initWithSuiteName:#"group.xxx.com"];,this code reset default userDefault. Actually,the correct code is : [[NSUserDefaults alloc] initWithSuiteName:#"group.xxx.com"]; enter link description here

Cannot access NSUserDefaults using app groups one to another

I'm working on an app and a widget that the widget needs to get data from app. I've used the following codes to read and write on NSUserDefaults. And also I used $(PRODUCT_BUNDLE_IDENTIFIER).widget for widget and $(PRODUCT_BUNDLE_IDENTIFIER) referring to this post. But widget cannot get the data from app or NSUserDefaults. How can I make it work?
func addTask(name: String?) {
let key = "keyString"
tasks.append(name!)
let defaults = NSUserDefaults(suiteName: "group.Mins")
defaults?.setObject(tasks, forKey: key)
defaults?.synchronize()
}
///////
let defaults = NSUserDefaults(suiteName: "group.Mins")
let key = "keyString"
if let testArray : AnyObject = defaults?.objectForKey(key) {
let readArray : [String] = testArray as! [String]
timeTable = readArray
timeTable = timeTable.sort(<)
print("GOT IT")
print("timetable: \(timeTable)")
}
To read and save from the same set of NSUserDefaults you need to the the following:
In your main app, select your project in the project navigator.
Select your main app target and choose the capabilities tab.
Switch on App Groups (this will communicate with the developer portal, as it is generating a set of entitlements, and relevant App Id and so forth).
Create a new container. According to the help, it must start with “group.”, so give it a name like “group.myapp.test”.
Select your Today Extension target and repeat this process of switching on app groups. Don’t create a new one, rather select this newly created group to signify that the Today Extension is a member of the group.
Write to your NSUserDefaults:
// In this example I´m setting FirstLaunch value to true
NSUserDefaults(suiteName: "group.myapp.test")!.setBool(true, forKey: "FirstLaunch")
Read from NSUserDefaults:
// Getting the value from FirstLaunch
let firstLaunch = NSUserDefaults(suiteName: "group.myapp.test")!.boolForKey("FirstLaunch")
if !firstLaunch {
...
}
Swift 4.x:
Write:
UserDefaults(suiteName: "group.myapp.test")!.set(true, forKey: "FirstLaunch")
Read:
UserDefaults(suiteName: "group.myapp.test")!.bool(forKey: "FirstLaunch")

Resources