How to make some config file to my program? - ios

How to make some config file to my program so program can load settings from it befoce starting?
Thanks a lot!

It sounds like what you are interested in is some kind of user preferences, yes?
use NSUserDefaults class for application configuration. To establish the initial set of values before user customization make a plist file with the appropriate keys and values corresponding to what you wish to use in your application.
example of registering your default settings file with the system:
// Load default defaults.
// Defaults need to be registered prior to interface loading.
NSString* defaultsPath = [[NSBundle mainBundle] pathForResource:#"defaults" ofType:#"plist"];
NSDictionary* defaultDict = [NSDictionary dictionaryWithContentsOfFile:defaultsPath];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults:defaultDict];
then in your application logic you can simply ask the NSUserDefaults object for a value (any of the plist supported types) for a given key using the various methods of NSUserDefaults:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
BOOL myBool = [defaults boolForKey:#"myBool"];
// you can also get strings, data, numbers, dates, arrays, and dictionaries

Related

iOS how to store data even if the app is closed

I am doing an iOS app. The goal is to send suggestions from user to improve the service I propose.
The app is a native app. I want to create a global NSMutableArray where I store all the suggestions. The problem is my device can be not connected to internet.
There is two cases:
If the device is connected when the user send his suggestion, it is send.
If not, the suggestion is saved in my NSMutableArray and send later.
Is it possible to create a global variable which store all my suggestions ? If my app is crashed/closed this variable can't be dealloc/reset.
Is a singleton enough to do this ?
first check for internet status of your device.if status is connected then send the array.if status in not connected then save the array into NSUserDefaults.To save suggestions array
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray * suggestions = [[NSMutableArray alloc] init];
[defaults setObject: suggestions forKey:#"suggestions"];
to Access those suggestions
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray * suggestions = [[NSMutableArray alloc]initWithArray:[defaultsobjectForKey:#"suggestions"]];
A singleton is not enough because you are going to lose all your data if your app is killed or crashes.
If there are only a few suggestions and they are short, the easiest approach would be to save them in your UserDefaults.
If you are going to save too much suggestions with long texts and several fields you will need to implement a database. Core Data would be a good solution for your problem.
An easy (single line of code) way to do this is to use plists and the command
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
on an NSArray
From the description:
Writes the contents of the array to a file at a given path.
If the array’s contents are all property list objects (NSString, NSData, NSArray, or NSDictionary objects), the file written by this method can be used to initialize a new array with the class method arrayWithContentsOfFile: or the instance method initWithContentsOfFile:. This method recursively validates that all the contained objects are property list objects before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.
In your example you would have (say) an NSArray of NSDictionaries with each NSDictionary containing the suggestions. Calling writeToFile would write it out in the event of no network availability. Then (say on app foreground event) you would read the file (arrayWithContentsOfFile call). If there is any content you would try to push to the server again.
You can use NSUserDefaults.
//write to NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSNumber numberWithInteger:userRatingInteger] forKey:#"userRating"];
[defaults synchronize];
//read from NSUserDefaults
NSNumber *userRatingNumber = [defaults objectForKey:#"userRating"];
if (userRatingNumber) { // the user has rated.
// Use the value as needed.
}

Get immutable system language list in iOS

If I use [NSLocale preferredLanguages] or [[NSUserDefaults standardUserDefaults] objectForKey:#"AppleLanguages"], the system will return a list of languages. However, this list can be changed by my app (without affecting the rest of the OS). Is there a way to get (a copy of) the actual global list that apps cannot change?
The purpose of this is to be able to override the language settings of the phone for my app, but also be able to revert back to the original settings. Without having access to the immutable global list of languages, I am not able to revert back again (especially if the user changes their language preferences). If I can get the immutable list, I can simply do something like this:
NSMutableArray *systemLanguages = [[someClass getImmutableSystemLanguages] mutableCopy];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (overrideLanguage {
[systemLanguages insertObject:#"languageCode" atIndex:0];
}
[defaults setObject:[systemLanguages copy] forKey"AppleLanguages"];
[defaults synchronize];

NSUserDefaults not being saved in simulator ,even though I use synchronize

I add a dictionary to NSUserDefaults and call 'synchronize' method,but when I close my app and reopen it the values which are saved in NSUserDefault are nil.
#define kStartTime #"startTime"
#define kEndTime #"endTime"
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *startTime=#"08:00";
NSString *endTime=#"18:00";
NSDictionary *dict=[[NSDictionary alloc] initWithObjectsAndKeys:startTime,kStartTime,
endTime,kEndTime,
nil];
[defaults registerDefaults:dict];
[defaults synchronize];
And in the viewDidLoad method I call this:
NSString *startTimeValue=[defaults stringForKey:kStartTime];
the startTimeValue is still nil When I reopen my app in simulator.Is UserDefaults can't save in Simulator???
My point is when i close my app and reopen it in simulator the values are gone.
After I searched the apple document ,I got this.
registerDefaults:.
As is said in Apple Document :Adds the contents of the specified dictionary to the registration domain.
*The contents of the registration domain are not written to disk;*you need to call this method each time your application starts.You can place a plist file in the application's Resources directory and call registerDefaults: with the contents that you read in from that file.
So the function of the registerDefaults: is setting Default values in app,The Default value will not stored in disk by synchronize
I think you try to read the value from NSUserDefaults before you have registered the defaults.
If you register defaults these values are not saved to disk, they will not persist to the next application launch. You have to register the default values every time you launch the app.
When you read an object from NSUserDefaults and you have not saved a value before, the registered default value will be returned. If you have saved a value before, this value will be returned.
In the code you posted you have not saved anything to userDefaults. So the value you have registered as default will be returned. If you haven't registered any values this will return nil.
The code that registers the defaults should be put in a method that runs very early in the application life cycle. I would recommend to use application:didFinishLaunchingWithOptions:
If you want to save multiple values to NSUserDefaults you have to use multiple setObject:forKey: calls.
registerDefaults: can not be used to save multiple keys to NSUserDefaults at the same time!
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSDictionary *dict=[[NSDictionary alloc] initWithObjectsAndKeys:startTime,#"kStartTime",
endTime,#"kEndTime",
nil];
[defaults registerDefaults:dict];
[defaults synchronize];
NSString *startTimeValue=[defaults stringForKey:#"kStartTime"];
NSLog(#"%#",startTimeValue);
you need to add keys like #"value" like this.
Now try this code....

Setting initial NSUserDefaults

I have seen some guides that say to do this, and others that say setting initial values and keys of NSUserDefaults this way will cause problems when an app is updated. I'm hoping I can definitively answer that here. In my appdelegate didFinishLaunchingWithOptions method I have:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults integerForKey:#"totalDays"]) {
// if there is no value for the key, set it to 1
[defaults setInteger:0 forKey:#"totalDays"];
}
if (![defaults objectForKey:#"currentDate"]) {
[defaults setObject:#"32 01" forKey:#"currentDate"];
}
if (! [defaults boolForKey:#"marked"]) {
[defaults setBool:NO forKey:#"marked"];
}
if (![defaults arrayForKey:#"checkedrows"]) {
NSMutableArray *arr1 = [NSMutableArray arrayWithArray:[defaults arrayForKey:#"checkedrows"]];
}
[defaults synchronize];
It might also be helpful to note, you don't "need" default values in there to use them. It might save you time from having to check them for null or zero values later in the app.
As the other answer stated, once values are saved to user defaults, it should persist from update to update and backup to backup. I've been using them for years with no issues with lost or corrupted data.
The data stored in the user defaults are save if the user updates the app. You will not get any problems with your code after an update.
You should not set the default values at all! Instead, use the handy method NSUserDefaults provides for exactly this purpose: -registerDefaults:. Call it early in your program's startup with a dictionary of the default values.
The advantage of this is that because -registerDefaults: is transient, you can tell the difference between "the user hasn't customized this preference" and "the user explicitly set this preference to the default value", which is important if you change default settings in a newer version of the program. It's also a little faster due to not needing to save to the disk.

Settings bundle not syncing up with NSUserDefaults [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Multivalue type settings bundle fields alway return null
I have a settings bundle in my iOS app which generates the following table in the settings app
In my app I attempt to generate the same table using NSUserDefaults and end up with this
My code to retrieve the values goes is:
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
ds->use_cache = [userDefaults boolForKey:#"use_cache"];
ds->high_bitrate = [userDefaults boolForKey:#"high_bitrate"];
and
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[[cell detailTextLabel] setText:[defaults stringForKey:#"version"]];
The stringForKey with the key "version" always returns a null value. I can't seem to get my app to recognise the default parameters I have defined in the settings bundle.
Here is my settings bundle
The default values for the settings should be set using the registerDefaults: method. This sets up an NSRegistrationDomain from which they will be available. An example for this is below. Thanks to jrturton & Matthias Bauch for pointing out the problem with my first answer that was previously referring to http://greghaygood.com/2009/03/09/updating-nsuserdefaults-from-settingsbundle.
NSDictionary *appDefaults = [ NSDictionary
dictionaryWithObject:#"default_version_value" forKey:#"version" ];
[ [ NSUserDefaults standardUserDefaults ] registerDefaults:appDefaults ];
NSUserDefaults *userDefaults = [ NSUserDefaults standardUserDefaults ];
Also note these default values need to be set every time the application starts as stated in the documentation for registerDefaults:.
The contents of the registration domain are not written to disk; you need to call this method each time your application starts. You can place a plist file in the application's Resources directory and call registerDefaults: with the contents that you read in from that file.

Resources