API to get an iPhones unique ID? - iphone

Two part question:
Does the iPhone have a unique ID other than it's MAC address?
If so, is there an API call I can use to get it?
(hopefully this isn't a duplicate, I couldn't find anything on SO)

The iPhone does have a unique identifier, called the UDID (this is the same identifier used when setting up a device for development or when doing ad hoc distribution). You can retrieve it as so:
NSString *uniqueIdentifier = [UIDevice currentDevice].uniqueIdentifier;

Related

Getting iPhone unique number

I need to get iPhone unique number programmatically. I know that apple will reject app if I try to gain iPhone serial number.
But may be there is a way to get any unique number of iPhone, so server can distinguish  one device from another.
For each iPhone, MAC address is unique ( except for iOS Simulator ). You can obtain the information to identify the device. This question will guide you to get MAC address. However, iOS7 disallows use of MAC address. Therefore, for iOS 6 or before, you can use MAC address; for the coming iOS 7, you can use the following method.
Since iOS 6, Apple suggests to use Advertising Identifier, which can be found in ASIdentifierManager class. Example code:
NSUUID *uuid = [ASIdentifierManager advertisingIdentifier];
Have you looked at identifierForVendor?
https://developer.apple.com/library/ios/documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html#//apple_ref/occ/instp/UIDevice/identifierForVendor
Apple describe it as:
An alphanumeric string that uniquely identifies a device to the app’s
vendor.
You should try this to get uid of your iPhone:
NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];

Restrict voting on an iPhone app to a particular iPhone device

I am working on a client iPhone app which allows users to rate various services. There is no registration or login.
The requirement is that a user can not repeatedly rate a service(although can change their rating). As things currently stand the app could be deleted, re-installed and the user could vote again.
We considered using the device id, however a colleague mentioned that Apple recommend against this. If I understand correctly in case a phone was returned to store, re-issued, and the new user then downloaded the same app. Seems like a pretty edge case to me, but I guess could happen within an enterprise.
Is there a smart way to restrict voting to a particular device? Perhaps using the keychain?
Any pointers greatly appreciated.
Its important to note the difference between a UDID and a UUID.
UDID "unique device id" is hardware specific. It never changes for a particular device. For this reason, it has become a privacy concern and Apple is blocking apps that try to use this. As a result, Apple has generated an opt-out-able "device id" hash, particularly for advertisement usage. This new ID hash is called IFA and is available in iOS 6.0+.
UUID "universally unique id" is not hardware specific. It is a hash used to identify a device; but not particularly an absolute value. For example, PhoneGap generates a UUID based on device properties; this is what you get when you do device.uuid. If you delete the app and reinstall, you will get a new id hash. UUID is not being blocked by Apple.
I think the best solution in your case would be to use the IFA, with OpenUDID as a backup for iOS < 6.0.
Here is the code we use. If IFA is not available, get OpenUDID. You must install OpenUDID, read more about that here, https://github.com/ylechelle/OpenUDID.
NSString* uuid = nil;
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
// IOS 6 new Unique Identifier implementation, IFA
uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
// Before iOS6 (or if IFA disabled) you shoud use a custom implementation for uuid
// Here I use OpenUDID (you have to import it into your project)
// https://github.com/ylechelle/OpenUDID
NSString* openUDID = [OpenUDID value];
uuid = [OpenUDID value];
}

Is it allowed to transfer iPhone UDID to my server?

My app has a feature which requires identifying each app users. I'm planning making the app sends UDID to my server. Server stores it, for later use.
I don't think that's a personal information, however, I want to know is it approvable or not in Apple's AppStore.
And, including transferring phone numbers. In the case of WhatsApp, it recognizes my friends' numbers automatically. I think that's impossible without some kind of data transfer.
You are allowed to transfer a device's UDID to your servers. That's what it's intended for.
Access to the UDID is grounds for rejection from the App Store. See an alternative to using the UDID at https://stackoverflow.com/a/10037636/1286639
Just make sure that it is no secret what your app does. If it transfers phone numbers to store those on your server then clearly mention this in the app's description or even ask the user for permission the first time.
That actually is a a reason to be rejected I think: not being clear about storing user's data on your own server/service.
Its important to note the difference between a UDID and a UUID.
UDID "unique device id" is hardware specific. It never changes for a particular device. For this reason, it has become a privacy concern and Apple is blocking apps that try to use this. As a result, Apple has generated an opt-out-able "device id" hash, particularly for advertisement usage. This new ID hash is called IFA and is available in iOS 6.0+.
UUID "universally unique id" is not hardware specific. It is a hash used to identify a device; but not particularly an absolute value. For example, PhoneGap generates a UUID based on device properties; this is what you get when you do device.uuid. If you delete the app and reinstall, you will get a new id hash. UUID is not being blocked by Apple.
I think the best solution in your case would be to use the IFA, with OpenUDID as a backup for iOS < 6.0.
Here is the code we use. If IFA is not available, get OpenUDID. [[You must install OpenUDID, read more about that here, https://github.com/ylechelle/OpenUDID.]]
NSString* uuid = nil;
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
// IOS 6 new Unique Identifier implementation, IFA
uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
// Before iOS6 (or if IFA disabled) you shoud use a custom implementation for uuid
// Here I use OpenUDID (you have to import it into your project)
// https://github.com/ylechelle/OpenUDID
NSString* openUDID = [OpenUDID value];
uuid = [OpenUDID value];
}

Any hack to get cell id on iPhone 3.0?

There was a hack for previous firmware using a reverse engineering of Code Telephony but it does not work anymore.
As far as I know, you can only get the UDID on the iphone.
[UIDevice currentDevice].uniqueIdentifier
A unique device identifier is a hash value composed from various hardware identifiers such as the device’s serial number. It is guaranteed to be unique for every device but cannot publically be tied to a user account. You can use it, for example, to store high scores for a game in a central server or to control access to registered products. The unique device identifier is sometimes referred to by its abbreviation UDID.

Unique identifier for an iPhone app

For an iPhone app that submits images to a server I need somehow to tie all the images from a particular phone together. With every submit I'd like to send some unique phone id. Looked at
[[UIDevice mainDevice] uniqueIdentifier]
and
[[NSUserDefaults standardDefaults] stringForKey:#"SBFormattedPhoneNumber"]
but getting errors in the simulator.
Is there an Apple sanctioned way of doing this?
What errors are you getting? [[UIDevice currentDevice] uniqueIdentifier] (edited to fix API, thanks Martin!) is the officially recommended way of doing this.
You can also use CFUUID to generate a UUID. Here's some code:
NSString *uuid = nil;
CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
if (theUUID) {
uuid = NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID));
[uuid autorelease];
CFRelease(theUUID);
}
By far the easiest and most appropriate way to obtain a unique identifier is to use the mechanisms Apple explicitly provides for obtaining one - [[UIDevice currentDevice] uniqueIdentifier]. You can not guarantee that the phone number will be unique to the device or that the device will even have a phone number. Beyond that, doing so is a horrible idea as it is a definite invasion of the user's privacy. Even the uniqueidentifier should be hashed if you are going to store it in any way.
In order to Persist the Unique Identifier you create between installations, you could use the Keychain Made easy with SSKeychain: Simply set your UUID as follows:
[SSKeychain setPassword:#"Your UUID" forService:#"com.yourapp.yourcompany" account:#"user"];
and then call it again anytime you need it:
NSString *retrieveuuid = [SSKeychain passwordForService:#"com.yourapp.yourcompany" account:#"user"];
Note: The services and accounts must match exactly.
Then, if the App is deleted and reinstalled, the UUID will persist with reinstallation.
If you then want to share this UUID across devices, set up your app to use iCloud. You can then store the UUID in NSUserDefaults, sync with KeyValueStore, and then set the UUID in the new devices keychain with the code above.
This answer would get extremely long if I typed code for all the above, but plenty of sample code around here to figure it all out.
Don't forget that in iOS 5 uniqueIdentifier will be deprecated you should use CFUUID instead of that
Interestingly, Apple has since deprecated the uniqueIdentifier in iOS 5 (as gN0Me mentioned). Here's the relevant TechCrunch article:
http://techcrunch.com/2011/08/19/apple-ios-5-phasing-out-udid/
Apple suggests that you no longer uniquely identify the device but instead identify the user. In most cases, this is excellent advice though there are some situations which still require a globally unique device ID. These scenarios are quite common in advertising. Hence, I wrote an extremely simple drop-in library which replicates the existing behavior exactly.
In a shameless plug of self promotion, I'll link it here in the hope that someone finds it useful. Also, I welcome all and any feedback/criticism:
http://www.binpress.com/app/myid/591
Nevertheless, in your particular situation I would advise skipping the globally unique ID functionality my library provides as it's a bit overkill for your situation. Instead, I would generate a simple CFUUID and store it in NSUserDefaults. This ID would be specific to your application but would allow you to group all the photos for that "app install" in your database.
In other words, by deprecating the uniqueIdentifier method, Apple is suggesting that you don't identify per device but instead per app install. Unless you are operating under specific conditions, chances are the per app ID fits your product better anyway.
This is an interesting problem that I am also looking into solving. Here is a scenario that I would like to address.
What happens when you sell your phone to another person... that Device ID will then belong to somebody else, so even if the app is removed from the iPhone, it could be re-added and all that data would then be re-associated to a new user... this is bad.
Using the Phone number with the Device ID MD5 would be a great solution. Another we came up with is having a SQL Lite DB with some token Hashed with the Device ID. Then when the app is removed the DB is killed and all the data is disassociated. I think that might be too brittle.
Any other ideas?
Rob Ellis (PhoneGap/Nitobi)
Use Apple's GenericKeyChain which is the best solution . Here is the working sample >>https://developer.apple.com/library/prerelease/ios/samplecode/GenericKeychain/Introduction/Intro.html
Have idea about KeyChainAccess >>https://developer.apple.com/library/mac/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-TP9
Haven't done iphone work, but how about taking a hash of something unique to the phone ... oh, say the phone number?
Getting iphone number
snippit:
NSString *phoneNumber = (NSString *) [[NSUserDefaults standardUserDefaults] objectForKey:#"SBFormattedPhoneNumber"]; // Will return null in simulator!
NSLog(#"Formatted phone number [%#]", phoneNumber);
I [recently] ran this code as-is on OS 2.2.1 [and OS 3.0].
It works as expected when run on the device, and returns my phone number with the full international dialing codes [ 1 in my case].
When run on the simulator, the value [returned] is a null string, so it only works on an actual iPhone device.
I did not test it on an iPod Touch.
...
Ran this code on a different device this week, and got a null value instead of the number.
On further research, it appears that the number returned by this code snippit is the number that is set up in iTunes for the device.
If you didn’t enter the iPhone’s number in iTunes at device activation, or perhaps (as in my case) if the default value wasn’t the iPhone’s number and you clicked OK anyway, such that iTunes doesn’t list the phone number when your iPhone is plugged in, this code will return a null string.
[Above is an edited concatenation of comments I recently posted to another article on this topic at http://www.alexcurylo.com/blog/2008/11/15/snippet-phone-number/]
Here is some more information on a way to get it from iTunes which may be useful for testing purposes.
I had success with such code:
- (NSString *)stringUniqueID {
NSString * result;
CFUUIDRef uuid;
CFStringRef uuidStr;
uuid = CFUUIDCreate(NULL);
assert(uuid != NULL);
uuidStr = CFUUIDCreateString(NULL, uuid);
assert(uuidStr != NULL);
result = [NSString stringWithFormat:#"%#", uuidStr];
assert(result != nil);
NSLog(#"UNIQUE ID %#", result);
CFRelease(uuidStr);
CFRelease(uuid);
return result;
}
You can use MAC address as a unique id. Following link will help you
How can I programmatically get the MAC address of an iphone