What approach should I use when advertisingIdentifier is nil? - ios

According to apple docs, sometimes it happens that the method [ASIdentifierManager sharedManager].advertisingIdentifier can return a nil value and I really need this value in my app:
https://developer.apple.com/library/prerelease/ios/documentation/AdSupport/Reference/ASIdentifierManager_Ref/index.html#//apple_ref/occ/instp/ASIdentifierManager/advertisingIdentifier
If the value is nil, wait and get the value again later. This happens,
for example, after the device has been restarted but before the user
has unlocked the device.
How long should I wait? What approach should I use in this case? Maybe keep trying to get the advertisingIdentifier until it is available? Or should I tell the user to try to restart the app? Any ideas?
Thanks.

You should manually create UUID and should save it in preferences.
NSString *UUID = [[NSUserDefaults standardUserDefaults] objectForKey:kApplicationUUIDKey];
if (!UUID) {
CFUUIDRef uuid = CFUUIDCreate(NULL);
UUID = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
[[NSUserDefaults standardUserDefaults] setObject:UUID forKey:kApplicationUUIDKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}

You can effectively get a notification when the user unlocks the phone using protected files and listening for applicationProtectedDataDidBecomeAvailable

Related

NSUserDefaults Boolean returns false when using app extension

I am using Notification Extension in my application to change the notification sound.
When the user turns off the UISwitch in the settings page I save in the NSUserDefaults a boolean to keep tracking of the state.
However I have 2 different storyboards for two different languages, each has its own style.
When I am using the storyboard A and I print the state of the boolean in the console, it's printing the state correctly. But when I change the language hence a different storyboard B loads up. The boolean is always returning false.
Although the boolean always return false, I have tested the sound of the notification, it works correctly.
Any idea why the boolean is always returning false? I need the correct value in order to show the state correctly of the ringtone in the settings page.
Here's the code I am using:
- (void)setPlayDefaultSound:(BOOL)playDefaultSound
{
NSUserDefaults *def = [[NSUserDefaults alloc] initWithSuiteName:#"group.com.xx.xxx.NotificationServices"];
[def setBool:playDefaultSound forKey:#"playDefaultSound"];
[def synchronize];
}
- (BOOL)playDefaultSound
{
NSUserDefaults *def = [[NSUserDefaults alloc] initWithSuiteName:#"group.com.xx.xxx.NotificationServices"];
return [def boolForKey:#"playDefaultSound"];
}
And here's a screenshot of the Info.plist of the Notification Services Extension:
You are creating new instances of NSUserDefaults each time. Use the same instance each time.
Use this instead.
- (void)setPlayDefaultSound:(BOOL)playDefaultSound
{
[[NSUserDefaults standardUserDefaults] setBool:playDefaultSound forKey:#"playDefaultSound"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (BOOL)playDefaultSound
{
return [[NSUserDefaults standardUserDefaults] boolForKey:#"playDefaultSound"];
}
There was a mismatch in the name in the capabilities, a typo.
It's working normally now.

Is there a way to consistently identify a user's device in your application?

Say I have an app - 'MyApp' - is there a way to consistently get a device identifier string within 'MyApp'?
i.e. Any time a user uses 'MyApp' on a particular device, I could call the API and get back the same string all the time?
identifierForVendor will change between installs, best to use CFUUIDCreate.
if ([[NSUserDefaults standardUserDefaults] valueForKey:#"UUID"] == nil) {
CFUUIDRef uuid = CFUUIDCreate(NULL);
NSString *uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
CFRelease(uuid);
[[NSUserDefaults standardUserDefaults] setObject:uniqueIdentifier forKey:#"UUID"];
}
The above will survive app re-installs.
Apple may reject your app for sending personally identifiable information. Use an advertising ID instead:
#import <AdSupport/AdSupport.h>
// Advertising ID
ASIdentifierManager *adManager = [ASIdentifierManager sharedManager];
NSUUID *uuid = [adManager advertisingIdentifier];
NSString *stringRepresentation = uuid.UUIDString;
Just make sure you abide by Apple's guidelines for UDID usage, including restrictions for users that have checked 'Restrict Ad Tracking' in Settings.

Reading settings bundle first time not returning correct values

I have some code where I am reading a switch value from my settings bundle however on some instances it reads the wrong value.
This is what my code looks like, it's in my app delegate applicationDidBecomeActive
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
NSNumber *branchString = [settings objectForKey:#"signout"];
BOOL userSignOut = [[settings objectForKey:#"signout"] boolValue];
NSLog(userSignOut ? #"Yes" : #"No");
What happens is when the app first loads I receive NO then when I switch to settings and turn my switch over to YES, when I log back in I still get NO however if I then switch between settings and my app again with out touch the switch in settings that's when I get YES even though it should have happened a step earlier.
Are you using this when setting the value?
[[NSUserDefaults standardUserDefaults] setObject:(id) forKey:(NSString *)];
[[NSUserDefaults standardUserDefaults] synchronize];
You can use NSUserDefaultsDidChangeNotification as observer.

NSUserDefaults do not save in iOS7?

In iOS6 the following code works fine. After the first launch, the hasLoaded BOOL is YES.
BOOL hasLoaded = [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultFirstLaunch];
if (!hasLoaded){
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kUserDefaultFirstLaunch];
[[NSUserDefaults standardUserDefaults] synchronize];
//do first launch stuff
}
But in iOS7, every time I run the app, hasLoaded is NO, even though I'm clearly setting it to YES and synchronizing. I have seen a couple other posts about this but no solutions. This would be such a HUGE bug that I can't believe it's really an Apple bug. Please tell me I'm wrong. Is it really true that no apps can reliably use NSUserDefaults on iOS7?
I've tested this on both the simulator and the device.
After looking at the com.domain.myapp.plist file in the Preferences folder I saw that the kUserDefaultFirstLaunch was actually "2", which is neither true or false. Turns out that I had a typo elsewhere that was using the kUserDefaultFirstLaunch key.
Dumb mistake, but I'm glad it's not a bug in the SDK.
I had the same problem and I think adding the following to the Application Delegate was what fixed it:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[NSUserDefaults standardUserDefaults] synchronize];
}
Take your value in string(or any other as per your requirement) and save the string in user defaults
NSUserDefaults *userdefault=[NSUserDefaults standardUserDefaults];
NSString *str=[NSString stringWithFormat:#"%#",[dicUser objectForKey:#"device_token"]];
[userdefault setObject:str forKey:#"YOURKEY"];

How can i get the UUID of my IPHONE in an application?

I am developing an application with external databases. For this motive, I have to save an uuid the only identifier for every user who registers. This way, it will differ if the user is a new user or is a user already registered in the application.
I create a new uuid with this:
NSUUID *uuid = [NSUUID UUID];
And i save that at external databases with the username. How do I obtain this information when the user enter again to the application? Have I to save it in some place of the device?
For one, you could could use NSUserDefaults
To cache uuid:
[[NSUserDefaults standardUserDefaults] setObject:uuid forKey:#"userIDKey"];
To retrieve uuid:
NSString *uuid = [[NSUserDefaults standardUserDefaults] objectForKey:#"userIDKey"];
Note that using the NSUUID class restricts you to an iOS target of iOS 6.0+. There are other ways to generate a UUID < iOS 6.0, e.g.
+ (NSString*)stringWithUUID {
CFUUIDRef uuidObj = CFUUIDCreate(nil);
NSString *uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(nil, uuidObj);
CFRelease(uuidObj);
return uuidString;
}

Resources