I have a question about uniqueIdentifier vs identifierforVendor. We use the UDID for login identification purposes and we are in the process of switching over to the new iOS 6 version of forVendor...
My questions are this
1) Is Apple rejecting apps that are still using uniqueIdentifier?
2) How can they reject this seeing as they don't allow first generation ipads to go up to 6.0?
PS - also found that identifierforVendor doesn't always work in 6.0, looks like it was resolved in 6.0.1
Here is the code I am using... do you think it will get rejected?
static inline NSString* UniqueDeviceId() {
if ([[[UIDevice currentDevice] systemVersion] compare:#"6.0.1" options:NSNumericSearch] != NSOrderedAscending)
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
return [[UIDevice currentDevice] uniqueIdentifier];
}
thanks
While I can't speak for the Apple review team. it is unlikely you will be rejected for using this deprecated API as long as your app supports a version of iOS that doesn't have the alternative.
I would update your code to properly check for the new method:
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
return [[UIDevice currentDevice] uniqueIdentifier];
}
now Apps are not permitted to access the UDID and must not use the uniqueIdentifier method of UIDevice. Please update your apps and servers to associate users with the Vendor or Advertising identifiers introduced in iOS 6
NSUUID *uuid = [[UIDevice currentDevice] identifierForVendor];
NSString *uuidString = [uuid UUIDString];
and must to add ADSupport framework
Related
Is there any way to check my application is enable with TouchID,
How can i check if my application is enable with TouchID,
For example :
DropBox have capability to enable figure print sensor enable. now is there any method to check if my application showing TouchID screen based on touchid enable.
You do not want to check the iOS version, sure, it might work but it is a bad practice. Check for the feature instead. See if LAContext is available.
if ([LAContext class]) {
// touch ID is available for the device
// call canEvaluatePolicy:error to see if the user has set a fingerprint.
}
According you use Objective-C
First, add method to check iOS Version
TouchID needs iOS8+ to work
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
Then, use LAContext canEvaluatePolicy:error: to evaluate if TouchID exist
Preflights an authentication policy to see if it is possible for authentication to succeed
- (BOOL)isTouchIDAvailable {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
return [[[LAContext alloc] init] canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil];
}
return NO;
}
assuming ios 8+ deployment target
var authError : NSError?
if LAContext().canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError) {
// do your thing dependent on touch id being useable on the device
}
in case you still need to support ios7 do the extra hoop
if NSClassFromString("LAContext") != nil && LAContext().canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError) {
I have to read the iOS device's udid in a project with base SDK 7.0 (I know I'm not supposed to, but I need to read it and the identifierForVendor is not an option). I have to to this only on iOS 6 devices, but the method uniqueIdentifier is not recognized because of the base SDK. Since I don't know how to determine the iOS version at compile time, I did the following:
#define SYSTEM_IS_IOS_7 ([[[UIDevice currentDevice] systemVersion] compare:#"7.0" options:NSNumericSearch] != NSOrderedAscending)
...
if (!SYSTEM_IS_IOS_7) {
SEL selector = NSSelectorFromString(#"uniqueIdentifier");
if ([[UIDevice currentDevice] respondsToSelector:selector]) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
[[[UIDevice currentDevice] class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
[invocation invoke];
NSString *udid = nil;
[invocation getReturnValue:&udid];
NSLog(#"%#", udid);
}
}
I'm running the code on iOS 6.1, the udid appears on the console, but the app crashes right after that with EXC_BAD_ACCESS in the main.m, with no message on the console. Any idea why and how to solve this?
My app is compatible with iOS5 and iOS6.
Until now I had no problem using:
NSString DeviceID = [[UIDevice currentDevice] uniqueIdentifier];
Now with iOS7 and with uniqueIdentifier not working anymore I changed to:
NSString DeviceID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
The problem is, this would not work for iOS5.
How can I achieve backward compatibility with iOS5?
I tried this, with no luck:
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
// iOS 6.0 or later
NSString DeviceID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
#else
// iOS 5.X or earlier
NSString DeviceID = [[UIDevice currentDevice] uniqueIdentifier];
#endif
The best and recommend option by Apple is:
NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
Use it for every device above 5.0.
For 5.0 you have to use uniqueIdentifier. The best to check if it's available is:
if (!NSClassFromString(#"ASIdentifierManager"))
Combining that will give you:
- (NSString *) advertisingIdentifier
{
if (!NSClassFromString(#"ASIdentifierManager")) {
SEL selector = NSSelectorFromString(#"uniqueIdentifier");
if ([[UIDevice currentDevice] respondsToSelector:selector]) {
return [[UIDevice currentDevice] performSelector:selector];
}
//or get macaddress here http://iosdevelopertips.com/device/determine-mac-address.html
}
return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
Why just not to use CFUUIDRef and be independent with iOS verion?
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
self.uuidString = (NSString *)CFUUIDCreateString(NULL,uuidRef);
CFRelease(uuidRef);
And of course remember calculated uuidString in the Keychain(in case of application removal)?
Here is written how to use keychain
As hard replacement of static macro, you can try dynamic if statement to check it.
UIDevice has property named 'systemVersion' and you can check this.
Apple doesn't allowed to add application to the app store that used the [UIDevice uniqueIdentifier] because the property become private in iOS SDK 6.0
What are the Alternatives?
you can use/create "your own" UDID:
+(NSString *)getUUID
{
CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);
NSString * uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);
CFRelease(newUniqueId);
return uuidString;
}
You should keep in mind that this method will produce a different id on every call so you should persist it some how, thus it is not an identical alternative to the UDID, but for most uses it is even better like that.
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
- (NSString*)deviceId {
NSString *udidString;
if (SYSTEM_VERSION_LESS_THAN(#"6.0")) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
udidString = [defaults objectForKey:#"udidKey"];
if (!udidString) {
CFUUIDRef identifierObject = CFUUIDCreate(kCFAllocatorDefault);
// Convert the CFUUID to a string
udidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, identifierObject);
[defaults setObject:udidString forKey:#"udidKey"];
[defaults synchronize];
CFRelease((CFTypeRef) identifierObject);
}
} else {
udidString = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
return udidString;
}
if gets warning on the line: udidString = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; it means the Xcode SDK is less than 6.0
(Xcode 4.3 contains iOS SDK 5.1, Xcode 4.5 contains iOS SDK 6.0)
to update Xcode iOS SDK:
simply download the newest Xcode available on App Store (Apple doesn't give an option to download only the SDK).
if want to keep current Xcode version just:
download the newest Xcode version.
copy iOS SDK Library from :
newestXcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
to
oldXcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
Reopen old Xcode and thats it!
How to detect my current device name through iOS?
Whether you are on an iPhone or a iPod Touch:
UIDevice *device = [UIDevice currentDevice];
NSString *systemName = [device systemName];
To detect the version of the OS:
UIDevice *device = [UIDevice currentDevice];
NSString *systemVersion = [device systemVersion];
To detect a specific model, you would need to test for some capability that only that model has, so to detect an iPhone 3GS, check for a video capability on the camera:
#define SOURCETYPE UIImagePickerControllerSourceTypeCamera
// does the device have a camera?
if ([UIImagePickerController isSourceTypeAvailable:SOURCETYPE]) {
// if so, does that camera support video?
NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:SOURCETYPE];
bool isA3GS = [mediaTypes containsObject:kUTTypeMovie];
}
Here is a class written by Erica Sadun that provides extensive capabilities for this:
http://github.com/erica/uidevice-extension/blob/master/UIDevice-Hardware.m
Check out the rest of the repo - there are a few more classes that would prove to be really useful for fine-grained device querying.
From the UIDevice.h file:
[[UIDevice currentDevice] name] // e.g. "My iPhone"
[[UIDevice currentDevice] model] // e.g. #"iPhone", #"iPod Touch"
[[UIDevice currentDevice] localizedModel] // localized version of model
[[UIDevice currentDevice] systemName] // e.g. #"iPhone OS"
[[UIDevice currentDevice] systemVersion] // e.g. #"2.0"
[[UIDevice currentDevice] uniqueIdentifier] // a string unique to each device based on various hardware info.
What you are looking for is this:
UIDevice *device = [UIDevice currentDevice];
NSString *model = [device model];
This will return whether the device is an iPhone or iPod touch