This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
iOS hardware parameters for unique id generation
I need to identify uniquely the IOS device instead of requiring sign-up in order to uniquely identify the consumers of my app, this data will be send to our servers by consuming WCF service actions.
How can I identify that?
PS. IP is not an option
UDID ([UIDevice currentDevice].uniqueIdentifier;) is deprecated, so i can't recommend you to use that...
What we do in our app is we generate a UUID and store it on the keychain, that together with a customer ID makes every "Profile" unique...
CFUUIDRef uuidObj = CFUUIDCreate(nil);//create the new UUID
NSString *uuidString = (NSString*)CFUUIDCreateString(nil, uuidObj);
P.S. Beware that apple does not like you to tie a user to the device, so better be prepared to explain why you need this.
If you're going to be only supporting iOS6 you can use the UIDevice identifierForVendor.
Related
I am trying to patch this security breach that Apple has identified. Only, the sample code (VerificationController) they provide uses this line:
[UIDevice currentDevice].uniqueIdentifier
Which has been deprecated and has had apps rejected from the app store. Any idea if this is OK again? or what is happening here?
Apple has updated the sample code deleting lines where UDID had been used.
In-App Purchase Receipt Validation on iOS
UDID vs UUID
From what I understand, Apple does not want developers to have access to a UDID (unique device identifier) anymore as it is not within an app's sandbox.
Think of a situation where a user gets a new iOS device (with a different UDID). Just because there is a new device does not necessarily mean there is a new user. Also, if someone gets a device previously used by someone else, we do not want to assume that because we have the same device, the same user must be using it.
Apple recommends using a UUID (universally unique identifier) for your apps instead. The only reason Apple allowed you to use UDID before was because they had not implemented UUID yet or had not considered the situations above (to my understanding). UUID's are generated for the object you want to keep track of (e.g. a user).
Basically, Apple's mentality is that you should keep track of users (or other instances), not devices.
Generating a UUID
To generate a UUID, try the including the following as a class method:
+ (NSString *)GetUUID
{
CFUUIDRef uuidReference = CFUUIDCreate(kCFAllocatorDefault);
NSString *theUUID = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuidReference) autorelease];
CFRelease(uuidReference);
return theUUID;
}
For my experience, I've called this method in the init method and stored the resulting NSString as a property of the instance that was just created.
Where did you hear that apps were rejected because of using it? Maybe they were using it maliciously but it is a public API. Also, look at the note on the page you linked to.
Note: This listing uses the symbols kSecTrustInfoExtendedValidationKey and SecTrustCopyInfo, which are not public API. Your app is allowed to use them for this specific purpose.
If they are even willing to let you use private APIs for this purpose, I doubt they would care about a public one.
Apple's problem with the UDID was always that they consider it private information, and so they were rejecting apps that sent it to, say, a server, without asking permission first. If you're just using it locally, I don't think you'll have trouble.
What is the best way to uniquely register an iOS Device, which won't be limited by future Apple restrictions?
My current approach to register an iOS device (basically to identify the device uniquely) is that I use the UDID of an iOS device to identify it and register it, and then after recognising it I perform the necessary actions.
The issue is that the UIDevice uniqueIdentifier property is deprecated. There are certain workarounds for that (as discussed in this question) which I'm aware of.
One possibility is to use the MAC address of an iOS device. However, I feel that Apple may restrict access to this information at some point in the future, as well.
Is there any other way (besides accessing the MAC address) to identify an iOS device, which we can rely on for the future?
Using Apple's preferred method of generating a CFUUIDRef is probably the better solution as I feel the MAC address may be removed in the future as well. If you use this and save it to your NSUserdefaults you will have it persist unless the user deletes the app. If you want to have a generated unique ID that you can share between apps or persist between installs you should look at using the UIPasteboard and saving your generated UID with a key that you share between apps.
//Create a unique id as a string
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
//create a new pasteboard with a unique identifier
UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:#"youruniquestring" create:YES];
[pasteboard setPersistent:YES];
//save the unique identifier string that we created earlier
[pasteboard setString:((__bridge NSString*)string)];
//accessing it
UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:#"youruniquestring" create:NO];
NSLog([pasteboard string]);
I have written a brief tutorial here but its basically the lines above: http://www.roostersoftstudios.com/2012/03/26/a-way-to-share-data-between-apps-on-a-given-ios-device/
Unless your application is for managing my Apple devices, it is the wrong approach. As a user, I don't want you to know which device I'm using. I want you to recognize me, whatever the device I use. I want to be able to replace a defective device. Apple will restrict more and more the access to this information.
[edit] I can't see how a MAC address could work. My iOS devices can have multiple.
Another option is dynamically generating your own UUID.
CFUUIDRef uuid = CFUUIDCreate(NULL);
CFStringRef generatedUuidStr = CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
NSString* uuidStr = [(NSString*)generatedUuidStr autorelease];
You could persist this UUID in NSUserDefaults for install based uniqueness. If device based uniqueness is truly the most important thing (so that after an uninstall and reinstall the id persists) you'll need a mechanism to persist the ID on the device. I think you could look into using the Keychain in order to persist that ID which should persist beyond app uninstall. You can even use an access group when adding the UUID to the keychain so that you could have a suite of apps that use the same UUID.
See apple's security framework reference for more info on saving keychain items and retrieving them.
http://developer.apple.com/library/ios/#DOCUMENTATION/Security/Reference/SecurityFrameworkReference/_index.html
The best approach I've seen is using the keychain. You can generate an UUID with the CFUUIDCreateString function and store it in the keychain. This data stays in the device between installs and restores from backups.
Use the devices Mac address. It's as unique as you could need I think.
How can I programmatically get the MAC address of an iphone
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UIDevice uniqueIdentifier Deprecated - What To Do Now?
As I expect you are aware of, the uniqueIdentifier in UIDevice is deprecated in iOS5. What I am looking for a basically the same functionality for iOS5.
What I understand from the documentation is that apple wishes that we (developers) create our own UUID (using CFUUIDCreate I guess) and store it in the NSUserDefaults. This, however, makes me shiver a bit and does not at all feel save. Feels a bit pointless to have a UUID in this case.
The reason I need an UUID is because I send of a bunch information including UUID to my servers in the auth process and would like to be able to skip some steps if the server can "guess" whom the user is next time the app gets launched or re-installed or another app implements my library. CFUUIDCreate does not seem to help me with this.
I took a quick look at gekitz as well, but as I understand it, it bases it solely on the MAC address of the Ethernet "card" in the phone. This is not suitable since I have a vague feeling that the MAC address is changeable. The uniqueIdentifier in UIDevice was
An alphanumeric string unique to each device based on various hardware details.
Currenly I wrote this code, which retrieves a UUID. But as soon as I clean in XCode and re-install the app on the phone, I get a new UUID.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *UUID = #"";
if (![defaults valueForKey:#"UUID"])
{
CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef UUIDSRef = CFUUIDCreateString(kCFAllocatorDefault, UUIDRef);
UUID = [NSString stringWithFormat:#"%#", UUIDSRef];
[defaults setObject:UUID forKey:#"UUID"];
}
else {
UUID = [defaults valueForKey:#"UUID"];
}
[deviceInformation setObject:UUID forKey:#"UUID"];
To sum it up, my question is the following:
Is there some solid way of creating an UUID that is based upon the device which is "hard" to tamper with and gives me as receiver a little something to depend and trust upon? This does not have to be based on the device, may be based on the app as a App UUID as long as its the same after a re-installation.
So far, the MAC seems to be the only known "stable" way to identify a device.
Have a look at Erica Sadun's UIDevice(Hardware) category, you'll notice that the only useful thing for identification is the MAC.
She also has a UIDevice(IOKit_Extensions) category which does provide IMEI and serial number. However, IOKit is private API. Erica wrote:
As iPhone evangelist Matt Drance tweeted, "IOKit is not public on iPhone. Lack of headers and docs is rarely an oversight."
So using IOKit might get you rejected.
As far as I know there is no way for a user to change the MAC without jailbreaking the device (and then he can do anything he wants anyway). So my suggestion is to ignore the jailbreakers and simply use a UUID based on the MAC.
Warning! MAC address APIs will not work in iOS 7.
This is my first post on here so be nice :) I am new to coding iOS and currently coding an app which uses a login system which communicates with the server and saves a users UDID. I need to app to check the UDID is on the server and if it matches to auto fill the Username UITextField in the login form.
Please could someone help me out or point me in the right direction.
Mike
Welcome to SO.
I assume you know how to get the UDID? If not, you get it as this
NSString *udid = [[UIDevice currentDevice] uniqueIdentifier];
Send this to your server (where you have a table with UDIDs and corresponding user information). Using PHP (or whatever language you are using), check if there is an entry for this UDID on the server. If yes, get the corresponding username and set it in the text field as
[textField setText:theUserName];
If you don't know how to send requests and get response from iOS apps, ASIHTTPRequest would be a good and easy way to begin.
If you need any other specific help, I would suggest updating the question.
Welcome to both iOS and Stackoverflow!
You could build a PHP service which would verify the UDID of your device and check if this device and username are already registered at your site, asuming you are keeping track of these registrations using a MySQL database, PHP could most certainly do the trick.
After verifying the existence of this device, you could use a JSON callback to send the UDID of the device to the iPhone.
As for parsing this JSON check out SBJSONParser.
It might be hard to pull this off in 2 languages, asuming you are new to both. This task is possibly completed in more secure or easier methods, but this might be a consideration to check every part of web communication that the iPhone has to offer
Good luck!
Bryan
Mike, Apple will be phasing out UDID so you should really look at a new approach to this. I would suggest a combination of app.domain and the device MAC number.
Then, have your app talk to your server using HTTPRequest and return the data as JSON and parse that on the app side.
GitHub already has a solution to UIDevice uniqueidentifier being dropped:
https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5
Project Description:
Description
Apple stopped supporting a unique identifier for iOS. This
source code solves the problem. It generates a unique identifier based
on the mac address of the device in combination with the bundle
identifier.
What you need to do:
copy NSString+MD5Addition and UIDevice+IdentifierAddition to your
project.
use [[UIDevice currentDevice] uniqueDeviceIdentifier] to retrieve the
unique identifier or
use [[UIDevice currentDevice] uniqueGlobalDeviceIdentifier] to
retrieve a global unique identifier (used for tracking between
different apps).
have fun and follow twitter.com/gekitz ;)
//Thanks to Erica Sadun for her UIDevice+Hardware Addition (used for
the mac address retrieval).
This question already has answers here:
Programmatically get own phone number in iOS
(9 answers)
Closed 9 years ago.
I need to get my iOS device's phone number programatically.
Via google I found this code:
NSString *num = [[NSUserDefaults standardUserDefaults] stringForKey:#"SBFormattedPhoneNumber"];
NSLog(#"Phone Number: %#", num);
But somewhere I read that if I use this code, Apple will reject my app.
Is there any way to get current device phone number without user entry?
No, the device's phone number is not available programmatically and still be approved by Apple, thankfully. I definitely don't want some free app I download out of curiosity to grab my phone number and start sending me spam SMS messages or have marketers calling me.
Your already have the answers:
Can any one pls help me is there any
way to get current device number
without user entry.
Yes, using the piece of code you have in your question.
And, YES, if you get phone number programmatically WITHOUT user input, your App will be rejected by Apple.
This is plain and simple.
If you need the number, ask for it from the user. If they trust you, they will input the number.