saving NSUserDefaults finished - iphone

I have noticed that the saving of NSUserDefaults takes a while.
How can I check if it has finished saving?
for example I do:
NSMutableArray *uld = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:#"testdata"]];
[uld addObject:teststring];
[[NSUserDefaults standardUserDefaults] setObject:uld forKey:#"testdata"];

You normally don't have to worry about NSUserDefaults it will store changes whenever there is time, if you need to make sure a changes has been written to disk call - (BOOL) synchronise, it will return YES if the defaults were correctly written to disc.
See the NSUserDefaults reference page at Apple

Usually, the synchronize process is asynchronous and normally people don't care about when it is saved into file system. But if you want to control you can call syncrhonize method to call it synchronously.
The thing is that, the NSUserDefaults will save your data to memory, and then in some time, it will save into the file system. However, you always deal with the interface level, so the data in memory or in file system doesn't have any difference

Related

How to save highscore and load highscore in a cocos2d iphone game

I have made my first iPhone game and i have it in the beta testing stage, but then i realised i am missing high score. I don't know how to add high score into the game and if anyone could help me it would be greatly appreciated, also could you tell me if it goes in the game scenes .m or .h file and where to declare it cheers.
Also i have tried to do this before and failed.
The best way to achieve this is using game center. It's very simple to integrate.
You could:
Use NSUserDefaults
Use plists
Use CoreData
If it is just a numerical value you want to store, defaults and plist are fine. But in case you want to store high scores, names, times, and/or scores of many/other users, et cetera, I would suggest using CoreData.
To save some data :
[[NSUserDefaults standardUserDefaults]setObject:yourNumber forKey:#"HighScore"];
to read it :
int high=[[NSUserDefaults standardUserDefaults]objectForKey:#"HighScore"];
This is objective c, cocos2d does not have some special way to save the data for you .
You better not use the game center only, but keep some copy at the user defaults .
First way: look at the plist this is the best way to store highscore load whatever your highScore into Plist and then retrieve that highscore from plist whenever you need. Look at this tutorial: Look at this tutorial
Second way is to store your highscore into NSUSerDefault and retrieve when you want.
NSuserDefault only vanish when you delete the app from simulator or device. So this is also solution for you..
Look at this
Save data to default:
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
[def setObject:highScore forKey:#"High Score"];
[def synchronize];

iOS - NSUbiquitousKeyValueStore doesn't "actually" sync

I am using NSUbiquitousKeyValueStore to sync my application preferences and I am testing the sync process using two devices iPhone 3GS and iPhone 4.
As I change a preference in one device (say iPhone 3GS), it syncs the preference to NSUbiquitousKeyValueStore using the following code:
NSUbiquitousKeyValueStore *keyStore = [NSUbiquitousKeyValueStore defaultStore];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[keyStore setObject:[userDefaults objectForKey:S_KEY_UI_SOUNDS]
forKey:S_KEY_UI_SOUNDS];
if ([keyStore synchronize]) {
NSLog(#"TO ICLOUD - UI SOUNDS %#", [keyStore objectForKey:S_KEY_UI_SOUNDS]);
}
However two issues occurs:
First: although being registered for NSUbiquitousKeyValueStoreDidChangeExternallyNotification, I never receive it on iPhone 4. So if the iPhone 4 is active while the iPhone 3GS changes a preference, the iPhone 4 becomes unaware of it.
Second: As the iPhone starts to sync the preferences from NSUbiquitousKeyValueStore, it never gets the new preference set using iPhone 3GS (see code below). This is despite of a successfully synchronization with NSUbiquitousKeyValueStore (the synchronize method returns YES).
NSUbiquitousKeyValueStore *keyStore = [NSUbiquitousKeyValueStore defaultStore];
if ([userDefaults synchronize]) {
NSLog(#"FROM - UI SOUNDS %#", [keyStore objectForKey:S_KEY_UI_SOUNDS]);
}
Is there a fix for that? or what am I doing wrong?
First -synchronize is not about "synchronizing with iCloud server". It's about synchronizing you changes and the local storage on disk. Once it's on disk, the underlying engine will push your changes to the cloud whenever it sees fit (generally after ~3s).
Second, you should subscribe to the store change notification.
In short, the first thing you should do when using NSUbiquitousKeyValueStore is something like:
store = [NSUbiquitousKeyValueStore defaultStore];
// subscribe immediately to any change that might happen to the store
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(storeDidChangeExternally:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:store];
// get any changes since the last app launch right now (safer)
[store synchronize];
Lastly, synchronization with the cloud happens at "proper time" (you can't control it for now).
Just to give you an idea, once you have "synchronized" your in-memory changes to the disk, the engine will generally start a synchronization with the cloud "soon" and push your changes.
The server will then push a notification to the other devices which will then schedule a synchronization with the cloud as well.
Under normal circumstances, it takes ~7s for devices to be in sync.

creating in-app settings for iPad applications

I want to create in-app settings for my iPad application. There are different alerts for different groups, so the user can select which alerts he/she wants in the application. I am putting a custom button which will look like checkbox so when user will click it, it will be highlighted.
Can anyone tell me where can I store the settings, do I need to save settings in keychain or somewhere else? Is there any tutorial for doing that?
I've found NSUserDefaults very helpful for stuff like this. Basically you do this to store values:
NSUserDefaults* defaults= [NSUserDefaults standardUserDefaults];
[defaults setBool:yourBool forKey:#"yourBoolKey"];
[defaults setInteger:yourInteger forKey:#"yourIntegerKey"];
[defaults synchronize];
And to get values:
NSUserDefaults* defaults= [NSUserDefaults standardUserDefaults];
yourBool= [defaults boolForKey:#"yourBoolKey"];
yourInteger= [defaults integerForKey:#"yourIntegerKey"];
To have default settings when the app first launches, you could just check a bool with the key #"AppHasStoredSettings" or something like that, which will be NO the first time, set your default settings, and then set it to YES.
The best thing would probably be a plist, which, in reality is a structured XML file with keys and values, but Apple abstracts most of that for you pretty well with some nice settings tools. Here's a few things to peruse to get a handle on the idea:
NSUserDefaults
User Defaults Programming Topics
Information about property list files
Luke put some helpful code, but look at these too for more examples and ways to use all the tools available.

Saving and retrieving data from NSMutablearray

I have a NSMutableArray holding string data.
I want to save my data.
When i turn off the application and relaunch the application my saved data need to be presented.
And I need to know where the file saved.
This question is basically the same as yours: Saving a NSArray
Another option is to save it in NSUserDefaults.

Is it possible to load/save the whole structure of plist in setting bundle using NSUserDefaults

I know it can use NSDictionary to load and save whole plist file on iphone document directory with its structure.
But is it possible to load/save the whole structure of plist in setting bundle using NSUserDefaults?
I'm pretty sure the following works for saving arrays in NSUserDefaults so it should work fine for a NSDictionary
[[NSUserDefaults standardUserDefaults] setObject:dictionary forKey:#"Dictionary"];
Hope that helps