231

How can I get a device's unique ID in Swift?

I need an ID to use in the database and as the API-key for my web service in my social app. Something to keep track of this devices daily use and limit its queries to the database.

11 Answers 11

481

You can use this (Swift 3):

UIDevice.current.identifierForVendor!.uuidString 

For older versions:

UIDevice.currentDevice().identifierForVendor 

or if you want a string:

UIDevice.currentDevice().identifierForVendor!.UUIDString 


There is no longer a way to uniquely identify a device after the user uninstalled the app(s). The documentation says:

The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them.


You may also want to read this article by Mattt Thompson for more details:
http://nshipster.com/uuid-udid-unique-identifier/

Update for Swift 4.1, you will need to use:

UIDevice.current.identifierForVendor?.uuidString 
Sign up to request clarification or add additional context in comments.

15 Comments

Yup. I figured that is the obvious thing to do, but I included it in the answer.
After app uninstall this number isn't the same anymore. Is there a way to track a device even after app uninstall ?
better question is, if its removed after uninstall, how do you delete their account on your server when the ID is no longer in use?
@jmcastel you'd save it in the keychain and every time your app launches just check for that before requesting a new one.
@UmairAfzal Lots of things don't work in the simulator. Did you try it on the real device?
|
22

You can use devicecheck (in Swift 4) Apple documentation

func sendEphemeralToken() { //check if DCDevice is available (iOS 11) //get the **ephemeral** token DCDevice.current.generateToken { (data, error) in guard let data = data else { return } //send **ephemeral** token to server to let token = data.base64EncodedString() //Alamofire.request("https://myServer/deviceToken" ... } } 

Typical usage:

Typically, you use the DeviceCheck APIs to ensure that a new user has not already redeemed an offer under a different user name on the same device.

Server action needs:

See WWDC 2017 — Session 702 (24:06)

more from Santosh Botre article - Unique Identifier for the iOS Devices

Your associated server combines this token with an authentication key that you receive from Apple and uses the result to request access to the per-device bits.

5 Comments

If I'm understand it correctly, token generation is performed using DCDevice.generateToken(), and every call generates a unique, random device_token. Hence, device_token isn't persistent, but ephemeral. What I don't understand is how the server is able to associate an ephemeral token with a device.
@user1118764 "Set two bits — Application server will responsible for sharing this token and set the bit value." read more here medium.com/@santoshbotre01/… and also here from official documentation developer.apple.com/documentation/devicecheck/… and 702 session developer.apple.com/videos/play/wwdc2017/702
FYI 24:06 is where the slide on DeviceCheck is discussed from WWDC 2017 Session 702 ^
Is there a way to do it without having a server doing additional request to apple? Is the data token from the generateToken not enough?
DeviceCheck does not provide a unique id string for the device, it just tells if the device has been used to redeem a reward for example or not.
11

For Swift 3.X Latest Working Code, Easily usage;

 let deviceID = UIDevice.current.identifierForVendor!.uuidString print(deviceID) 

3 Comments

This changes whenever use uninstall and install the app again.
This is just a copy of @Atomix & JayprakasDubey's answers
You can use the FCUUID pod (github.com/fabiocaccamo/FCUUID) that allows you to get an uuid that won't change even after the app is deleted.
9

You can use identifierForVendor public property present in UIDevice class

let UUIDValue = UIDevice.currentDevice().identifierForVendor!.UUIDString print("UUID: \(UUIDValue)") 

EDIT Swift 3:

UIDevice.current.identifierForVendor!.uuidString 

END EDIT

Screenshot for property hierarchy

2 Comments

This is just a copy of @Atomix answer
You can use the FCUUID pod (github.com/fabiocaccamo/FCUUID) that allows you to get an uuid that won't change even after the app is deleted.
3

Swift 2.2

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let userDefaults = NSUserDefaults.standardUserDefaults() if userDefaults.objectForKey("ApplicationIdentifier") == nil { let UUID = NSUUID().UUIDString userDefaults.setObject(UUID, forKey: "ApplicationIdentifier") userDefaults.synchronize() } return true } //Retrieve print(NSUserDefaults.standardUserDefaults().valueForKey("ApplicationIdentifier")!) 

2 Comments

It is useless if the user deletes application because userdefaults also get deleted with application uninstallation.
What happens when user updates the app? This will give different results right unless you have persisted in Keychain?
3

In swift 4,5 You can get UUID using below code.

print(UIDevice.current.identifierForVendor!.uuidString) 

Output

enter image description here

Apart from that you can get multiple properties from connected Device.

 UIDevice.current.name // e.g. "My iPhone" UIDevice.current.model // e.g. @"iPhone", @"iPod touch" UIDevice.current.localizedModel // localized version of model UIDevice.current.systemName // e.g. @"iOS" UIDevice.current.systemVersion // e.g. @"15.5" 

Comments

2

On iOS we commonly mistake things such as UDID & UUID string. Actually both are different.

Looking based on most of the answers given is UUID, where else the question was about UDID.

  1. UUID - Is not unique, every app re-install or factory reset the identifier value will change.

    Example : UUID().uuidString

  2. UDID - Is a unique value. This specifically refers to your device, can't be obtain programatically.

Comments

0

If, like me, you were trying to get the unique device identifier for devices you manage with a mobile device management (MDM) system, you can use Managed App Configuration.

There is a special part of UserDefaults you can use that your MDM system can change and you can read on the app side:

UserDefaults.standard.object(forKey: "com.apple.configuration.managed")

For the device ID, you could decide to call your key deviceID (but it can be anything) and read it from the UserDefaults above in your app. Then on the MDM side you would set this variable to the device's ID.

In most MDM systems, there are several variables, among which are device serial number, device ID, MEID, mac address, etc. In the app's managed configuration section, add your key deviceID and set it to a variable like serial number provided by your MDM system. The MDM system will then update the special managed UserDefaults section with that key and a different value depending on the device where it's installed, allowing you to access the value from the app.

Comments

-1
if (UIDevice.current.identifierForVendor?.uuidString) != nil { self.lblDeviceIdValue.text = UIDevice.current.identifierForVendor?.uuidString } 

2 Comments

Please comment your code and/or offer details and an explanation of how this solves the posted question.
The suggested edit queue is full. if you could peruse those and just click accept on one or two o them. this might be used for push notification registration right?
-3
class func uuid(completionHandler: @escaping (String) -> ()) { if let uuid = UIDevice.current.identifierForVendor?.uuidString { completionHandler(uuid) } else { // 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. // https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { uuid(completionHandler: completionHandler) } } } 

Comments

-22

I've tried with

let UUID = UIDevice.currentDevice().identifierForVendor?.UUIDString 

instead

let UUID = NSUUID().UUIDString 

and it works.

1 Comment

NSUUID().UUIDString will give you a new string every time

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.