Why is implementing a while statement in viewDidLoad not working? [duplicate] - ios

I need to load user data, but I need to do it looped. (always loading). My code is
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferenceName"];
And also, whenever I make an if function, for example
if (t1activity == "active")
{
//code here
}
I get an error saying Expected identifier or '('
Thanks so much! (objective-c)

In the case the value differs only between YES/NO is better to provide a BOOL.
BOOL isUserActive = [[NSUserDefaults standardUserDefaults] boolForKey:#"preferenceName];
and the set method:
[[NSUserDefaults standardUserDefaults]
setBool:YES
forKey:#"preferenceName"];
Then the decision is simpler:
if(isUserActive) {
{
//code here
}
I was curious to know, how often the NSUSerDefaults do update. Here the Apple Docs.
NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value. The synchronize method, which is automatically invoked at periodic intervals, keeps the in-memory cache in sync with a user’s defaults database.

Related

error: Trying to put the stack in unreadable memory at: 0x7ffeeafe2af0 : using userDefaults

I am doing a project in objective-c and I have to store some values in userDefaults. I am already did the same thing in the same project. It was working fine but now I am trying to add some values in userDefaults it showing error while fetch any data from userDefaults. I am adding the datas as,
NSString * totalBitValue = [NSString stringWithFormat:#"%.6f Bit",
totalValue /
[[[NSUserDefaults standardUserDefaults] objectForKey:#"Bit"] floatValue]];
[[NSUserDefaults standardUserDefaults]setObject:totalBitValue forKey:#"totalBTCValue"];
[[NSUserDefaults standardUserDefaults]setFloat:totalUSDValue forKey:#"totalUsedValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
and the error as ,
error: Trying to put the stack in unreadable memory at: 0x7ffeeafe2af0
I got the error in the following line,
if( [[NSUserDefaults standardUserDefaults] objectForKey:#"CoinValue"] != nil) {
[[self ValueLabel] setText: [NSString stringWithFormat:#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"CoinValue"] ]];
}
Anyone can help me.Thanks in advance
The reason for your issue is because your code gets recursion.
As I understand, you used NSNotificationCenter to observer key NSUserDefaultsDidChangeNotification. So whenever NSUserDefaults is updated, it will trigger defaultsChanged method. But inside it, you continue to change NSUserDefaults, set new value for totalBTCValue and totalUSDValue (as I guess) which makes defaultsChanged be called again and leads to recursion.
To fix the issue, you shouldn't update NSUserDefaults inside defaultsChanged method

How do I store permanent data

I am new to iOS development and have the following problem.
EXPLANATION:
I have an app which consists of several mini games. Each mini game is available through in app purchase. However the mini game availability is saved in a BOOL variable like this:
_miniGamesArray = [[NSMutableArray alloc] init];
NSMutableDictionary *mutDictMg0 = [NSMutableDictionary dictionaryWithCapacity:3];
[mutDictMg0 setValue:[self.gameAvailabilityMutableArray objectAtIndex:0] forKey:#"GameAvailable"];
[_miniGamesArray addObject:mutDictMg0];
PROBLEM:
Each time I start the app the game availability is checked from the self.gameAvailabilityMutableArray which is set to:
- (NSMutableArray *)gameAvailabilityMutableArray
{
if (!_gameAvailabilityMutableArray)
{
//[_gameAvailabilityMutableArray addObjectsFromArray:#[#1,#0,#0,#0 ,#0,#0,#0,#0]];
_gameAvailabilityMutableArray = [[NSMutableArray alloc] initWithArray:#[#1,#1,#1,#1 ,#1,#1,#1,#1]];
}
return _gameAvailabilityMutableArray;
}
When the customer buys a mini game I want the array to be set to (example):
#[#1,#1,#0,#0 ,#0,#0,#0,#0]]
TRIED SOLUTIONS:
I tried to implement the array by calling the iTunes server and writing the data. However, the time to recieve the request is greater then the app loading time. The second problem arrises if there is no internet connection, then the app crashes.
I also tried using .plist files. I don't know why but writing to the plist file doesn't change it's contest all the time! Some times it works , sometimes it doesn't... Sometimes the app loads the values correctly sometimes it mixes them with the last values.
QUESTION:
Is there a way to store permanent app data which is being checked when the app loads beside plists?
Thank you for your time.
save your data in NSUserDefaults.then use below conditions for app start first time or handle another conditions.
BOOL iSFirstTime = [[NSUserDefaults standardUserDefaults] boolForKey:#"AppStartFirstTime"];
if (!iSFirstTime) {
NSLog(#"Application start first time");
[[NSUserDefaults standardUserDefaults] setValue:#"ImgDownloaded" forKey:#"ProductIDDef"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"AppStartFirstTime"];
}else{
// NSLog(#"we are here");
if ([[[NSUserDefaults standardUserDefaults] valueForKey:#"ProductIDDef"] isEqualToString:#"ImgDownloaded"]) {
NSLog(#"All transaction and Image Downloading has been perform successfully");
}else{
//If any network problem or any thing else then handle here.
}
}
}
You can save the data in NSUserDefaults using the following code:
[[NSUserDefaults standardUserDefaults] setObject:_gameAvailabilityMutableArray forKey:#"gameArray"];
[[NSUserDefaults standardUserDefaults] synchronise];
and you can retrieve the array using
_gameAvailabilityMutableArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"gameArray"];

Store a value for the app's running time

I need to store a boolean value that would persist only for the app's running time. When the user quit the app (from the background as well) that variable should reset to default. How can I do this?
I tried constants. I keep constants in a separate .h file. In it I declared it like this.
const BOOL hasShownTutorial = NO;
And in the view controller,
if (hasShownTutorial == NO) {
[self showAppTutorial];
hasShownTutorial = YES;
}
I get an error at hasShownTutorial = YES; saying Read-only variable is not assignable.
I also tried going about this using NSUserDefaults. But the thing is the value is stored for good once you set it. Is there a way to clear it up when the app quits?
I'd appreciate your input and suggestions.
Thank you.
Store it in NSUserDefaults under a specific key.
[[NSUserDefaults standardDefaults] setBool:<myBool> forKey:#"myKey"];
Then to retrieve it later.
BOOL b = [[NSUserDefaults standardDefaults] boolForKey:#"myKey"];
If you want to clear the data.
NSString *domain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:domain];
For example, in your AppDelegate's implementation of -applicationWillTerminate:, just clear the data.
- (void)applicationWillTerminate:(UIApplication *)application
{
NSString *domain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:domain];
}
Edit: If the first method of clearing the data does not work, you can use the class method +resetStandardUserDefaults. For example the following would clear the current defaults.
[NSUserDefaults resetStandardUserDefaults];
A third possiblity is to specifically remove a property.
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"myKey"];
You can't change const value since it is a read only memory. Use static keyword instead.

NSUserDefault is being cleared automatically after random period of time

I am using these methods to save and get data from NSUserDefaults. But NSUserDefaults is being cleared automatically in device after random period of time. I checked the project-
I am not saving any nil or empty string using saveUserName method.
Not using removeObjectForKey, removePersistentDomainForName to reset NSUserDefault.
Code...
+(NSString *) getUserName{
return [[NSUserDefaults standardUserDefaults] objectForKey:kAccUserNameKey];
}
+(void)saveUserName:(NSString *) value {
[[NSUserDefaults standardUserDefaults] setObject:value forKey:kAccUserNameKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
After saving data using saveUserName, I get data properly using getUserName, even after restarting app. But It has been reported that data is being lost sometimes.(getUserName is called from didFinishLaunchingWithOptions and applicationWillEnterForeground) Why NSUserDefault is resetting? any idea??
From documentation
(NSUserDefaults *)standardUserDefaults
Description
Returns the shared defaults object. If the shared defaults object does not exist yet, it is created with a search list containing the names of the following domains, in this order:
NSArgumentDomain
A domain identified by the application’s bundle identifier
NSGlobalDomain
NSRegistrationDomain
Is that means, sometimes shared object does not exist yet and its returning nil? whats the solution?
Did you create NSRegistrationDomain domain for your data dictionary via -registerDefaults: ?
As documentation says:
At launch time, an app should register default values for any
preferences that it expects to be present and valid.
You can do it like this, to make NSUSerDefaults work properly:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary * defaultsDictionary = #{kAccUserNameKey : #"default name"}
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary];
return YES;
}
In the defaultsDictionary you should specify all data keys you will use in app with their default values.

CFUUID - creating ONCE & using throughout life of app

I wrote these lines in my code:
CFUUIDRef identifier = CFUUIDCreate(NULL);
NSString *identifierString = (NSString*)CFUUIDCreateString(NULL, identifier);
NSLog(#"%#",identifierString);
[self setValue:identifierString forKey:kParamNameDeviceId];
But these lines are getting called every time when the app launches.
Now my question is, how can the following be achieved?
Create CFUUID.
Store it in some variable in such a way that, when next time my app starts, it should not create a new CFUUID. It should look for the previously created CFUUID and return it.
In short, I want a CFUUID be created ONCE and used throughout the life of the app (till it gets uninstalled).
easiest way is to store it in NSUserDefaults
NSString *identifierString = [[NSUserDefaults standardUserDefaults] objectForKey:#"myID"];
if (!identifierString) {
CFUUIDRef identifier = CFUUIDCreate(NULL);
identifierString = (NSString*)CFUUIDCreateString(NULL, identifier);
[[NSUserDefaults standardUserDefaults] setObject:identifierString forKey:#"myID"];
}
NSLog(#"%#",identifierString);
/* ... */
Create once. Add it in NSUSerDefaults and check whether you have a UUID stored already before creating one. Simple Pseudo code,
NSString *CFUUID = nil;
if (![[NSUserDefaults standardUserDefaults] objectForKey:#"UUID"]) {
//create CFUUDID.
[[NSUserDefaults standardUserDefaults] setObject:CFUUID forKey:#"UUID"];
}
else
{
CFUUID = [[NSUserDefaults standardUserDefaults] objectForKey:#"UUID"];
}
If you are storing identifier on server to keep track of important information regarding unique user than i suggest you store identifierString in "KeyChain" which keeps that identifier even if you application has been deleted by user.
NSUserDefaults keep data until app is deleted. Keychain keeps data even if app is deleted.
I had similar case so this might help if your case is equivalent to mine.

Resources