What else do I need to save a variable into disc? - ios

I'me trying to save a variable into hard drive to load it on my app startup. I do the following:
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
votesFile = [documentsDirectory stringByAppendingPathComponent:#"votes.dat"];
Yet, this is creating no file, at least that I can see. When I try to do this:
[votes writeToFile:votesFile atomically:YES]; //votes!=nil
and then
votes = [[NSMutableDictionary alloc] initWithContentsOfFile: votesFile];
it does nothing for me, votes == nil
What am I missing here?

If you are using a NSDictionary with NSStrings as keys, and NSNumbers as values, those classes are compatible with Archiving and Unarchiving pattern, so you can use NSUserDefaults to store your data, and load it the next time you run the application.
To save your data:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:yourVotesDictionary forKey:aKey];
[defaults synchronize]; //This is very important when you finish saving all your data.
To load your data:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *votes = [defaults objectForKey:yourNSString];
As you can see, NSUserDefaults is a dictionary, and it behaves like that.
Hope it helps,
have a good day.

There can be various errors using writeToFile:atomically: which is why it returns a BOOL. You should have something like:
if(![votes writeToFile:votesFile atomically:YES]) {
NSLog(#"An error occurred");
}
If you are getting an error there you have an issue with your NSDictionary.

Related

Not finding NSUserDefaults plist in simulator folder

I know that there are other same questions as mine. But I think that I have tried everything and I still can't be able to find the NSUserDefaults plist file in my simulator folder. I made sure that I got the right ID for the simulator and I wasn't able to find the NSUserDefaults plist as I want to check exactly what values are being saved. Does anyone know what is the exact name of the file that I should be searching for?
For info, I am searching in the following path:
/Users/username/Library/Developer/CoreSimulator/Devices/<device_id>/data/Library/Preferences
Does anyone know if I am doing it wrong? How can I find that file?
Thank you for your help!
you can print the location by asking at runtime.
Each time you compile and run simulator the folders may differ from before.
how to write NSUserDefaults
NSUserDefaults *userdef = [NSUserDefaults standardUserDefaults];
[userdef setObject:#"testString" forKey:#"testkey"];
[userdef synchronize]; //dont forget synchoniszing after setting new objects
how to read NSUserDefaults
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
NSString *result = [defs objectForKey:#"testkey"];
NSLog(#"read out userdefs = %#",result);
If you did not set any NSUserDefaults yet, there is no file.
Otherwise where is your <BundleIdentifier>.<appName>.plist ?
NSArray *path = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryFolder = [path objectAtIndex:0];
NSString *appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleIdentifier"];
NSString *userdefFile = [NSString stringWithFormat:#"%#/Preferences/%#.plist", libraryFolder, appID];
NSLog(#"NSUserDefaults File located at: %#", userdefFile);

How to set all data into a new .m file and run it in another?

So i would like to make a file called "SavedData.h" "SavedData.m" and store all my games saved data in these files...
How would I wire the whole process up to run in my "MainView.h" and "MainView.m"
I'm not that experienced with xcode...
The action in the MainView.m:
- (IBAction)btncheck:(id)sender {
if ([answer isEqualToString:#"Pizza Pie"]) {
//Name:Pizza Pie *SAVED
NSString *savestring = _textbox.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:savestring forKey:#"savedstring"];
[defaults synchronize];
}
_textbox is my textField
and in my SavedData.m:
//Name:Pizza Pie
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *loadstring = [defaults objectForKey:#"savedstring"];
[_textbox setText:loadstring];
}
How is this done?
& is it even possible?
I think you're aiming to save state to a file and restore it later (you wouldn't use source files for this, there's no compiler on the phone). Steps are:
Put whatever you want to save in a dictionary:
NSMutableDictionary *myState = [NSMutableDictionary dictionary];
myState[#"foo"] = #"bar";
Get a path to where you're app is allowed to save:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *pathFile = [paths[0] stringByAppendingPathComponent:#"mystate.plist"];
Save:
[myState writeToFile:pathFile atomically:YES];
Read it later:
myState = [[NSDictionary alloc] initWithContentsofFile:pathFile];
You can also build a mutable dictionary this same way (replace NSDictionary in the last line with NSMutableDictionary).

`[NSUserDefaults standardUserDefaults]` returns nil

I want to save some user preferences, but
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
just returns nil.
iOS-Developper Library says, that this should return the existing shared defaults object or create one if none exists... What am I missing?
I also use Appirater and there all this stuff seems also not to work...
This code gets called when the user pushes a button...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int index = ([defaults integerForKey:#"BackgroundColorSpecifier"]+ 1)%self.backgroundColors.count;
[defaults setInteger:index forKey:#"BackgroundColorSpecifier"];
[defaults synchronize];
This gets called in application: didFinishLaunchingWithOptions:
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
[standardDefaults registerDefaults:#{#"BackgroundColorSpecifier": #0}];
[standardDefaults synchronize];
When I debug this code snippets the green "position-indicator" jumps around in a very strange manner...
I don't have any clue, whats going on... Please help!
This is far more likely to be a problem with the debugger than anything else, particularly with your other issues. I've seen similar things in my own projects but don't have a reliable way of clearing it out other than the usual restart / clean options.
NSLogs will usually give more consistent results than the debugger if the debugger is having an off day.
NSUserDefaults isn't broken. We'd have heard about it by now.
you can use this function to log you userDefaults dic
- (void)logCache
{
NSDictionary * dic = [[NSBundle mainBundle] infoDictionary];
NSString *bundleId = [dic objectForKey: #"CFBundleIdentifier"];
NSUserDefaults *appUserDefaults = [[NSUserDefaults alloc] init];
NSDictionary *cacheDic = [appUserDefaults persistentDomainForName: bundleId];
NsLog(#"cacheDic::%#",cacheDic);
}

NSUserDefaults Contains Value Or Not?

How to know whether NSUserDefaults contains any value?How to check whether its empty?
There isn't a way to check whether an object within NSUserDefaults is empty or not.
However, you can check whether a value for particular key is nil or not.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSObject * object = [prefs objectForKey:#"your_particular_key"];
if(object != nil){
//object is there
}
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
NSString *string = [data objectForKey:#"yourKey"];
if(string==nil)
NSlog(#"nil")
Take a look at NSUserDefault documentation
// For saving the values
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// saving an NSString
[userDefaults setObject:#"Ttest" forKey:#"key"];
// --- For Retrieving
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *myString = [userDefaults stringForKey:#"key"];
To check whether a specific value is set or not, no matter of its location (global or application's), check the returned value of -[NSUserDefaults objectForKey:]
id obj = [[NSUserDefaults standardUserDefaults] objectForKey:#"My-Key-Name"];
if (obj != nil) {...}
To check if the application (bundle) has any settings stored in user defaults:
NSUserDefaults* sdu = [NSUserDefaults standardUserDefaults];
NSString* bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary* mainBundleSettings = [sdu persistentDomainForName:bundleId];
NSLog(#"%#", mainBundleSettings);
If you are interested in all possible values for which -[NSUserDefaults objectForKey:] will return something, including system global settings, simply call
NSDictionary* allPossibleSettings = [sdu dictionaryRepresentation];
NSUserDefaults is never empty. It combines global settings, bundle's settings, temporary data and maybe something else. For example, if you call:
[[NSUserDefaults standardUserDefaults] objectForKey:#"NSBoldSystemFont"]
you will get the #"LucidaGrande-Bold" string value which will be taken from global settings, even when your application has never set this value.

How do I save user preferences for my iPhone app?

The question title pretty much gives it away - I'd like my app to remember a few things. It's some sort of calculator, so it should save the last used values and some user selectable settings.
Basically I'd like to save a handful of floats and BOOLs and load them again the next time the app loads.
What's the best and easiest way to do that?
Thanks!!
One of the easiest ways would be saving it in the NSUserDefaults:
Setting:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:value
forKey:key];
// – setBool:forKey:
// – setFloat:forKey:
// in your case
[userDefaults synchronize];
Getting:
[[NSUserDefaults standardUserDefaults] objectForKey:key];
– boolForKey:
and
– floatForKey: in your case.
Besides the very good NSUserDefaults approach, there is another easy way to store data from an NSArray,NSDictionary or NSData in a file. You can use these methods as well:
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
respectively (for a NSDictionary):
+ (id)dictionaryWithContentsOfFile:(NSString *)path
you just have to give a valid path to a location. According to the iOS Application Programming Guide, the /Library/Caches directory would be the best place to store data that you need to persist between app launches. (see here)
In order to store/load a dictionary from a filed called "managers" in your document directoy you could use these methods:
-(void) loadDictionary {
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
//create a destination file name to write the data :
NSString *fullFileName = [NSString stringWithFormat:#"%#/managers", cacheDirectory];
NSDictionary* panelLibraryContent = [NSDictionary dictionaryWithContentsOfFile:fullFileName];
if (panelLibraryContent != nil) {
// load was successful do something with the data...
} else {
// error while loading the file
}
}
-(void) storeDictionary:(NSDictionary*) dictionaryToStore {
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the
//cache directory:
NSString *fullFileName = [NSString stringWithFormat:#"%#/managers", cacheDirectory];
if (dictionaryToStore != nil) {
[dictionaryToStore writeToFile:fullFileName atomically:YES];
}
}
Anyway this approach is very limited and you have to spend a lot of extra work if you want to store more complex data. In that case the CoreData API is very very handy.
In Swift:
Setting
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(value, forKey: key)
// userDefaults.setFloat(12.34, forKey: "myFloatKey")
// userDefaults.setBool(true, forKey: "myBoolKey")
Note that for iOS 8 and later, calling userDefaults.synchronize() is not recommended.
Getting
let userDefaults = NSUserDefaults.standardUserDefaults()
if let value = userDefaults.objectForKey(key) {
print(value)
}
Note that userDefaults.boolForKey and userDefaults.floatForKey both return non optional values, so they would never be nil (only false or 0.0).
Further reading
NSUserDefaults — A Swift Introduction
You are looking for NSUserDefaults
Swift 4 / Linux
Apparently something has changed. Now there's the UserDefault class.
Check these links:
https://developer.apple.com/documentation/foundation/userdefaults
https://www.hackingwithswift.com/read/12/2/reading-and-writing-basics-userdefaults

Resources