CFUUID - creating ONCE & using throughout life of app - ios

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.

Related

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

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.

Intermittently Calling [NSUserDefaults synchronize] Returns Success but isn't shown during ObjectForKey

I have 2 applications sharing data via the NSUserDefaults, initWithSuite ID. Using iOS Dev Center.
One in 2 attempts the following code block apparently fails to write my dictionary object to the shared UserDefault area, I use the BOOL response from Synchronise to check the success. eg, (4 NSData objects, one, or more, or all of the items might fail to write to storage).
I use [[NSUUID uuid] UUIDString] as a key [EDIT: Been told in comments that this changes value?, Tried a Static String same result, 25% fail rate]
Any help will be greatly received.
Writer - Application 1
NSUserDefaults *myDefaults = [[NSUserDefaults alloc]
initWithSuiteName:FRGFileShareID];
NSString *uuid = [[NSUUID UUID] UUIDString];
[myDefaults setObject:**customObjectDict** forKey:uuid];
BOOL successSave = [myDefaults synchronize];
if (!successSave) {
DLog(#"Failed To Save To Defaults");
}
Reader - Application 2
NSUserDefaults *myDefaults = [[NSUserDefaults alloc] initWithSuiteName:FRGFileShareID];
if ([myDefaults objectForKey:uuid]) {
[mediaArray addObject:[myDefaults objectForKey:uuid]];
[myDefaults removeObjectForKey:uuid];
}
If i log out [[myDefaults dictionaryRepresentation] allKeys] im lucky if any of my keys are there.
Again with this working 75% of the time, im not sure whats causing the intermittency but its killing the usability of my feature.
You have not pass the value to NSUserDefault, change the code like this,
[myDefaults setObject:uuid forKey:"myDict Object"];
[myDefaults synchronize];

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.

How to check if the app was already installed

I have an app that I want to make an update for it.
I have a list of items in application, but now I want to add versions for this items, so when item will be updated it will be marked as Updated. or if i will add a new item it will be marked like New.
But now for new users that install app first time all items should be new, and for users that already have app on their devices all items should be without any mark intially.
I don't have any user defaults now in app so i can't check some value.
How can I check if app was already installed on device?
The answer is that you cannot know it if you didn't store any information that would help you to check if the user is updating the app or installing it from scratch.
You can use this code to know it, starting from the version you would implement it in.
BOOL versionUpgraded;
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
NSString *previousVersion = [prefs stringForKey:#"appVersion"];
if ([[NSUserDefaults standardUserDefaults] stringForKey:#"appVersion"] != nil)
{
// See if version is the same as the previous one. If NOT, it is an Update.
versionUpgraded = !([previousVersion isEqualToString: version]);
}
// No "appVersion" means new install.
else
{
versionUpgraded = YES;
}
if (versionUpgraded)
{
[[NSUserDefaults standardUserDefaults] setObject:version
forKey:#"appVersion"];
[[NSUserDefaults standardUserDefaults] setObject:previousVersion
forKey:#"prevAppVersion"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
What you can also do is to check if there is any data you cache, store etc. Anything in NSUserDefaults, or any kind of database, or Documents folder, that would mean that the app was already installed.

Resources