timeIntervalSince1970 crashing with NSUserDefaults - crash

I'm trying to show a UIALertView every 4 days. But getting a crash because:
NSInvalidArgumentException', reason: '-[__NSCFString timeIntervalSince1970]:
I tried using different approaches like the following code here: https://stackoverflow.com/a/4278151/1014564 resulting in the same crash.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *firstLaunchDate = [defaults objectForKey:#"timeStamp"];
NSDate *dateNow = [[NSDate alloc] init];
if (!firstLaunchDate){
NSString *nowTimestamp = [NSString stringWithFormat:#"%f", [[NSDate date] timeIntervalSince1970]];
[defaults setObject:nowTimestamp forKey:#"timeStamp"];
[defaults synchronize];
} else if (([dateNow timeIntervalSince1970] - [firstLaunchDate timeIntervalSince1970]) > 86400*4){
///UIAlertView Here..
}
Answers appreciated and will be accepted. I know it's probably a simple mistake, I'm past the point of sleepy atm.

nowTimestamp = [NSString stringWithFormat:...];
[defaults setObject:nowTimestamp forKey:#"timeStamp"];
then
NSDate *firstLaunchDate = [defaults objectForKey:#"timeStamp"];
So you're basically setting an NSString in the user defaults, but you expect to get back an NSDate. Since NSUserDefaults ain't magic, that won't happen. If you want to store a date, store it using
[defaults setObject:[NSDate date] forKey:#"timeStamp"];
and only then you can use timeIntervalSince1970 on the object you get back from NSUserDefaults.

Related

NSUserDefaults Arrays

I need two NSMutableArray that will contain NSString.
These arrays are:
ListOFUserNames=[NSMutableArray array];
SituationstoName =[NSMutableArray array];
I have two different sets of strings that go into each mutable array.
After named gets added to Listofusernames
Situation gets added to SituationstoName
[ListOFUserNames addObject:AfterNamed];
[SituationstoName addObject:Situation];
I am trying to save listofusernames and situationstoname with their respective strings.
NSUserDefaults *something = [NSUserDefaults standardUserDefaults];
[something setObject:ListOFUserNames forKey:#"somedata"];
[something synchronize];
NSUserDefaults *something2 = [NSUserDefaults standardUserDefaults];
[something2 setObject:SituationstoName forKey:#"somedata2"];
[something2 synchronize];
In the method that loads them, nothing comes out.
The code for that method is:
NSUserDefaults *somet = [NSUserDefaults standardUserDefaults];
NSUserDefaults *somet2 = [NSUserDefaults standardUserDefaults];
ListOFUserNames = [somet objectForKey:#"somedata"] ;
SituationstoName = [somet2 objectForKey:#"somedata2"] ;
[somet synchronize];
[somet2 synchronize];
The problem is that it is not loading the strings that are saved in the mutable arrays.
//initialise array
NSMutableArray *listOFUserNames=[[NSMutableArray alloc] init];
NSMutableArray *situationstoName =[[NSMutableArray alloc] init];
//add content in the array
[listOFUserNames addObject:AfterNamed];
[situationstoName addObject:Situation];
(Before storing also check if your array contains objects or is empty.)
//Store these array in `NSUserDefaults`
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:listOFUserNames forKey:#"NameData"];
[userDefaults setObject:situationstoName forKey:#"SituationData"];
[userDefaults synchronize];
//Access data where ever you want to be
//(listOFUserNames and situationstoName must be array)
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
listOFUserNames = [userDefaults objectForKey:#"NameData"] ;
situationstoName = [userDefaults objectForKey:#"SituationData"] ;

How to save fields correctly with NSUserDefaults?

I'm creating a program that saves a String from one text field and an integer from a second text field. I am trying to use NSUserDefaults, but I can't seem to get either of them to save correctly when I run the program. It crashes when I press the save button with the breakpoint while handling the NSUserDefaults. Am I doing something wrong? I skimmed through the documentation, but it didn't help. Can I even use 2 different instances of NSUserDefaults?
- (IBAction)save:(id)sender {
//Save stuff fropm textfields
NSString* name = _nameText.text;
int count = [_countText.text intValue];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[[NSUserDefaults standardUserDefaults] setObject:name forKey:#"name"];
[[NSUserDefaults standardUserDefaults] setInteger:count forKey:#"count"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (IBAction)load:(id)sender {
//Load stuff from NSUserDefaults
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString* loadstring = [defaults objectForKey:#"name"];
_nameText.text = loadstring;
NSUserDefaults* defaults2 = [NSUserDefaults standardUserDefaults];
NSInteger loadint = [defaults2 integerForKey:#"count"];
_countText.text = [NSString stringWithFormat:#"%li", (long)loadint];
}
Declare defaults = [NSUserDefaults standardDefaults]; in your viewDidLoad (and NSUserDefaults* defaults; in .h) and use this code:
- (IBAction)save:(id)sender {
//Save stuff fropm textfields
NSString* name = _nameText.text;
int count = [_countText.text intValue];
[defaults setObject:name forKey:#"name"];
[defaults setInteger:count forKey:#"count"];
[defaults synchronize];
}
- (IBAction)load:(id)sender {
//Load stuff from NSUserDefaults
_nameText.text = [defaults stringForKey:#"name"];
_countText.text = [NSString stringWithFormat:#"%li", (long)[defaults integerForKey:#"count"]];
}

If statement in NSUserDefault when loading a string

I have the following code for saving a value and an string. I want to use If statement to check my value.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"Baseball bat" forKey:#"Weaponsname"];
NSInteger Attack1 = [defaults integerForKey:#"Attack"];
NSString *Weapon = [defaults stringForKey:#"Weaponsname"];
if([Weapon isEqual: #"Baseball bat"]){
[defaults setInteger:(Attack1+50) forKey:#"Attack"];
NSLog(#"Baseball bat");
}
[defaults synchronize];
So if i have the Baseball bat, the Attack should increase by 50. But it doesn't.
What wrong with the code?
Thanks
For string comparison you should use the isEqualToString method found in the NSString class.
if ([Weapon isEqualToString:#"Baseball bat"]) { ... }

NSUserDefaults Reset First Run

I have an app already in the AppStore that uses NSUserDefaults. Some of the defaults are Default settings that I go ahead and set when the app is first launched, and then the user is allowed to change them later if they wish. So, in my AppDelegate appDidFinishLaunchingWithOptions I put:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (! [defaults boolForKey:#"notFirstRun"]) {
[defaults setBool:YES forKey:#"notFirstRun"];
[defaults setInteger:0 forKey:#"verseKey"];
[defaults synchronize];
}
The issue I am having now is I want to add some more Default settings in the NSUserDefault category, so I want to make it look like this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (! [defaults boolForKey:#"notFirstRun"]) {
[defaults setBool:YES forKey:#"notFirstRun"];
NSString *smalltitle = #"4";
NSString *smallarticle = #"3";
[defaults setObject:smalltitle forKey:#"Title"];
[defaults setObject:smallarticle forKey:#"Article"];
[defaults setInteger:0 forKey:#"verseKey"];
[defaults synchronize];
}
I know that this will cause an issue for those who have already downloaded the app, and are merely updating it. They will not run that code because the notFirstRun Bool has already been set to YES. Any thoughts on what I should do here?
The proper solution is to not actually populate NSUserDefaults with default values. Instead, use the registerDefaults: method.
At app startup you do:
NSUserDefaults *default = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults:#{
#"Title" : #"4",
#"Article" : #"3",
#"verseKey" : #0
}];
That's it. Call this every time the app is run. These defaults are not actually persisted. The value is only returned if there isn't already an explicit value for the key. You can update these defaults all you want without affecting any existing values.
Make a new notFirstRun Boolean value (i.e. notFirstRunTwo). That will be 'NO' for existing users, too.
I suggest to do the following :
check userdefaults for stored app version if it is equal to the current or not , if not.
store the current app version and do your first launch initialization
the code
`
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *appVersion = [NSString stringWithFormat:#"%#",[[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleShortVersionString"]];
if (! [defaults objectForKey:appVersion ])
{
/// store the current version and then do your first run functions
[defaults setObject:[NSNumber numberWithInt:1] forKey:appVersion];
/// here do your first run
......
}`

NSUserDefaults not saving in table cell

When I replace the #"hello" with titlestring the table, the cell shows up blank, If i leave the hello, everything works, including the "detailsstring". I don't know why it's doing that since detailsstring is set up exactly the same as titlestring.
here is the code:
in the .m file I have
#synthesize detailsstring;
#synthesize titlestring;
and it's all defined the same in the .h in the .m I have this as well:
- (void)viewDidLoad{
titlestring =[[NSUserDefaults standardUserDefaults] objectForKey:#"titletext"];
detailsstring = [[NSUserDefaults standardUserDefaults] objectForKey:#"details"];
tabledata = [[NSArray alloc] initWithObjects:#"hello", nil];
tablesubtitles = [[NSArray alloc] initWithObjects:detailsstring, nil];
[super viewDidLoad];
}
Now, I'm saving those Userdefaults in another controller. Here is the save button action in a different view controller:
- (IBAction)saveButton:(id)sender {
NSUserDefaults *titletext = [NSUserDefaults standardUserDefaults];
[titletext setObject:titleTextfield.text forKey:#"titletext"];
NSUserDefaults *details = [NSUserDefaults standardUserDefaults];
[details setObject:detailstextfield.text forKey:#"details"];
NSUserDefaults *categoryUser = [NSUserDefaults standardUserDefaults];
[categoryUser setInteger:selectedCategory forKey:#"category"];
}
What am I doing wrong?
First of all, one instance of NSUserDefaults is sufficient for all three modifications. To 'push' the changes to the file system immediately, you can call [userDefaults synchronize];. Otherwise there is no guarantee that your changes are saved instantly. Apple suggests only to call this method if you cannot wait for the changes to be saved.
- (IBAction)saveButton:(id)sender {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:titleTextfield.text forKey:#"titletext"];
[userDefaults setObject:detailstextfield.text forKey:#"details"];
[userDefaults setInteger:selectedCategory forKey:#"category"];
[userDefaults synchronize];
}
In your viewDidLoad: method, try to output the saved values to test your application's integrity:
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"details"]);