UIDevice uniqueIdentifier deprecated - What to do now?

IosDeprecatedUidevice

Ios Problem Overview


It has just come to light that the UIDevice uniqueIdentifier property is deprecated in iOS 5 and unavailable in iOS 7 and above. No alternative method or property appears to be available or forthcoming.

Many of our existing apps are tightly dependent on this property for uniquely identifying a particular device. How might we handle this problem going forward?

The suggestion from the documentation in 2011-2012 was:

> Special Considerations > > Do not use the uniqueIdentifier property. To create a unique identifier specific > to your app, you can call the CFUUIDCreate function to create a UUID, and write > it to the defaults database using the NSUserDefaults class.

However this value won't be the same if a user uninstalls and re-installs the app.

Ios Solutions


Solution 1 - Ios

A UUID created by CFUUIDCreate is unique if a user uninstalls and re-installs the app: you will get a new one each time.

But you might want it to be not unique, i. e. it should stay the same when the user uninstalls and re-installs the app. This requires a bit of effort, since the most reliable per-device-identifier seems to be the MAC address. You could query the MAC and use that as UUID.

Edit: One needs to always query the MAC of the same interface, of course. I guess the best bet is with en0. The MAC is always present, even if the interface has no IP/is down.

Edit 2: As was pointed out by others, the preferred solution since iOS 6 is -[UIDevice identifierForVendor]. In most cases, you should be able use it as a drop-in replacement to the old -[UIDevice uniqueIdentifier] (but a UUID that is created when the app starts for the first time is what Apple seems to want you to use).

Edit 3: So this major point doesn't get lost in the comment noise: do not use the MAC as UUID, create a hash using the MAC. That hash will always create the same result every time, even across reinstalls and apps (if the hashing is done in the same way). Anyways, nowadays (2013) this isn't necessary any more except if you need a "stable" device identifier on iOS < 6.0.

Edit 4: In iOS 7, Apple now always returns a fixed value when querying the MAC to specifically thwart the MAC as base for an ID scheme. So you now really should use -[UIDevice identifierForVendor] or create a per-install UUID.

Solution 2 - Ios

You can use your alternative for Apple UDID already. Kind guy gekitz wrote category on UIDevice which will generate some kind of UDID based on device mac-address and bundle identifier.

You can find code on github

Solution 3 - Ios

Based on the link proposed by @moonlight, i did several tests and it seems to be the best solution. As @DarkDust says the method goes to check en0 which is always available.
There are 2 options:
uniqueDeviceIdentifier (MD5 of MAC+CFBundleIdentifier)
and uniqueGlobalDeviceIdentifier(MD5 of the MAC), these always returns the same values.
Below the tests i've done (with the real device):

#import "UIDevice+IdentifierAddition.h"

NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

> XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI)UDID
> XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI)GlobalAppUDID

> XXXX21f1f19edff198e2a2356bf4XXXX - (3G)UDID
> XXXX7dc3c577446a2bcbd77935bdXXXX - (3G)GlobalAppUDID

> XXXX21f1f19edff198e2a2356bf4XXXX - (GPRS)UDID
> XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS)GlobalAppUDID

> XXXX21f1f19edff198e2a2356bf4XXXX - (AirPlane mode)UDID
> XXXX7dc3c577446a2bcbd77935bdXXXX - (AirPlane mode)GlobalAppUDID

> XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi)after removing and > reinstalling the app XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) after > removing and installing the app

Hope it's useful.

EDIT:
As others pointed out, this solution in iOS 7 is no longer useful since uniqueIdentifier is no longer available and querying for MAC address now returns always 02:00:00:00:00:00

Solution 4 - Ios

check this out,

we can use Keychain instead of NSUserDefaults class, to store UUID created by CFUUIDCreate.

with this way we could avoid for UUID recreation with reinstallation, and obtain always same UUID for same application even user uninstall and reinstall again.

UUID will recreated just when device reset by user.

I tried this method with SFHFKeychainUtils and it's works like a charm.

Solution 5 - Ios

Create your own UUID and then store it in the Keychain. Thus it persists even when your app gets uninstalled. In many cases it also persists even if the user migrates between devices (e.g. full backup and restore to another device).

Effectively it becomes a unique user identifier as far as you're concerned. (even better than device identifier).

Example:

I am defining a custom method for creating a UUID as :

- (NSString *)createNewUUID 
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return [(NSString *)string autorelease];
}

You can then store it in KEYCHAIN on the very first launch of your app. So that after first launch, we can simply use it from keychain, no need to regenerate it. The main reason for using Keychain to store is: When you set the UUID to the Keychain, it will persist even if the user completely uninstalls the App and then installs it again. . So, this is the permanent way of storing it, which means the key will be unique all the way.

     #import "SSKeychain.h"
     #import <Security/Security.h>

On applictaion launch include the following code :

 // getting the unique key (if present ) from keychain , assuming "your app identifier" as a key
       NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
      if (retrieveuuid == nil) { // if this is the first time app lunching , create key for device
        NSString *uuid  = [self createNewUUID];
// save newly created key to Keychain
        [SSKeychain setPassword:uuid forService:@"your app identifier" account:@"user"];
// this is the one time process
}

Download SSKeychain.m and .h file from sskeychain and Drag SSKeychain.m and .h file to your project and add "Security.framework" to your project. To use UUID afterwards simply use :

NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];

Solution 6 - Ios

Perhaps you can use:

[UIDevice currentDevice].identifierForVendor.UUIDString

Apple's documentation describes identifierForVender as follows:

The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

Solution 7 - Ios

You may want to consider using OpenUDID which is a drop-in replacement for the deprecated UDID.

Basically, to match the UDID, the following features are required:

  1. unique or sufficiently unique (a low probability collision is probably very acceptable)
  2. persistence across reboots, restores, uninstalls
  3. available across apps of different vendors (useful to acquire users via CPI networks) -

OpenUDID fulfills the above and even has a built-in Opt-Out mechanism for later consideration.

Check http://OpenUDID.org it points to the corresponding GitHub. Hope this helps!

As a side note, I would shy away from any MAC address alternative. While the MAC address appears like a tempting and universal solution, be sure that this low hanging fruit is poisoned. The MAC address is very sensitive, and Apple may very well deprecate access to this one before you can even say "SUBMIT THIS APP"... the MAC network address is used to authenticate certain devices on private lans (WLANs) or other virtual private networks (VPNs). .. it's even more sensitive than the former UDID!

Solution 8 - Ios

I'm sure Apple have annoyed many people with this change. I develop a bookkeeping app for iOS and have an online service to sync changes made on different devices. The service maintains a database of all devices and the changes that need to be propagated to them. Therefore it's important to know which devices are which. I'm keeping track of devices using the UIDevice uniqueIdentifier and for what it's worth, here are my thoughts.

  • Generate a UUID and store in user defaults? No good because this does not persist when the user deletes the app. If they install again later the online service should not create a new device record, that would waste resources on the server and give a list of devices containing the same one two or more times. Users would see more than one "Bob's iPhone" listed if they re-installed the app.

  • Generate a UUID and store in the keychain? This was my plan, since it persists even when the app is uninstalled. But when restoring an iTunes backup to a new iOS device, the keychain is transferred if the backup is encrypted. This could lead to two devices containing the same device id if the old and new devices are both in service. These should be listed as two devices in the online service, even if the device name is the same.

  • Generate a hash the MAC address and bundle id? This looks like the best solution for what I need. By hashing with the bundle id, the generated device id is not going to enable the device to be tracked across apps and I get a unique ID for the app+device combination.

It's interesting to note that Apple's own documentation refers to validating Mac App Store receipts by computing a hash of the system MAC address plus the bundle id and version. So this seems allowable by policy, whether it passes through app review I don't yet know.

Solution 9 - Ios

It looks like for iOS 6, Apple is recommending you use the NSUUID class.

From the message now in the UIDevice docs for uniqueIdentifier property:

> Deprecated in iOS 5.0. Use the identifierForVendor property of this > class or the advertisingIdentifier property of the ASIdentifierManager > class instead, as appropriate, or use the UUID method of the NSUUID > class to create a UUID and write it to the user defaults database.

Solution 10 - Ios

May help: use below code it will always Unique except you erase(Format) your device.

Objective-C:

Option 1: This will change on every install

UIDevice *uuid = [NSUUID UUID].UUIDString;

Option 2: This will be unique per vendor/Developer Apple Account

UIDevice *myDevice = [UIDevice currentDevice];
NSString *uuid = [[myDevice identifierForVendor] UUIDString];

Swift 5.X:

Option 1: This will change on every install

let uuid = UUID().uuidString

Option 2: This will be unique per vendor/Developer Apple Account

let myDevice = UIDevice.current
let uuid = myDevice.identifierForVendor?.uuidString

Solution 11 - Ios

I would also suggest changing over from uniqueIdentifier to this open source library (2 simple categories really) that utilize the device’s MAC Address along with the App Bundle Identifier to generate a unique ID in your applications that can be used as a UDID replacement.

Keep in mind that unlike the UDID this number will be different for every app.

You simply need to import the included NSString and UIDevice categories and call [[UIDevice currentDevice] uniqueDeviceIdentifier] like so:

#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]

You can find it on Github here:

UIDevice with UniqueIdentifier for iOS 5


Here are the categories (just the .m files - check the github project for the headers):

> UIDevice+IdentifierAddition.m

#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"

#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>

@interface UIDevice(Private)

- (NSString *) macaddress;

@end

@implementation UIDevice (IdentifierAddition)

////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Private Methods

// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
    
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2");
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", 
                           *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);
    
    return outstring;
}

////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Public Methods

- (NSString *) uniqueDeviceIdentifier{
    NSString *macaddress = [[UIDevice currentDevice] macaddress];
    NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];  
    NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];
    NSString *uniqueIdentifier = [stringToHash stringFromMD5];  
    return uniqueIdentifier;
}

- (NSString *) uniqueGlobalDeviceIdentifier{
    NSString *macaddress = [[UIDevice currentDevice] macaddress];
    NSString *uniqueIdentifier = [macaddress stringFromMD5];    
    return uniqueIdentifier;
}

@end

> NSString+MD5Addition.m:

#import "NSString+MD5Addition.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString(MD5Addition)

- (NSString *) stringFromMD5{
    
    if(self == nil || [self length] == 0)
        return nil;
    
    const char *value = [self UTF8String];
    
    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(value, strlen(value), outputBuffer);
    
    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
        [outputString appendFormat:@"%02x",outputBuffer[count]];
    }
    return [outputString autorelease];
}

@end

Solution 12 - Ios

You can achieve from this code : UIDevice-with-UniqueIdentifier-for-iOS-5

Solution 13 - Ios

The MAC address can be spoofed which makes such an approach useless for tying content to specific users or implementing security features like blacklists.

After some further research it appears to me that we're left without a proper alternative as of now. I seriously hope Apple will reconsider their decision.

Maybe it would be a good idea to email Apple about this topic and / or file a bug / feature request on this since maybe they are not even aware of the full consequences for developers.

Solution 14 - Ios

UIDevice identifierForVendor introduced in iOS 6 would work for your purposes.

identifierForVendor is an alphanumeric string that uniquely identifies a device to the app’s vendor. (read-only)

@property(nonatomic, readonly, retain) NSUUID *identifierForVendor

The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps onthe same device that come from different vendors, and for apps on different devices regardles of vendor.

Available in iOS 6.0 and later and declared in UIDevice.h

For iOS 5 refer this link UIDevice-with-UniqueIdentifier-for-iOS-5

Solution 15 - Ios

Using the SSKeychain and code mentioned above. Here's code to copy/paste (add SSKeychain module):

+(NSString *) getUUID {

//Use the bundle name as the App identifier. No need to get the localized version.

NSString *Appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];    

//Check if we have UUID already

NSString *retrieveuuid = [SSKeychain passwordForService:Appname account:@"user"];

if (retrieveuuid == NULL)
{

    //Create new key for this app/device

    CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);

    retrieveuuid = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);

    CFRelease(newUniqueId);
    
    //Save key to Keychain
    [SSKeychain setPassword:retrieveuuid forService:Appname account:@"user"];
}

return retrieveuuid;

}

Solution 16 - Ios

Following code helps to get UDID:

        udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        NSLog(@"UDID : %@", udid);

Solution 17 - Ios

This is code I'm using to get ID for both iOS 5 and iOS 6, 7:

- (NSString *) advertisingIdentifier
{
    if (!NSClassFromString(@"ASIdentifierManager")) {
        SEL selector = NSSelectorFromString(@"uniqueIdentifier");
        if ([[UIDevice currentDevice] respondsToSelector:selector]) {
            return [[UIDevice currentDevice] performSelector:selector];
        }
    }
    return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}

Solution 18 - Ios

From iOS 6 onwards, we have NSUUID class which complies RFC4122

Apple Link : apple_ref for NSUUID

Solution 19 - Ios

iOS 11 has introduced the DeviceCheck framework. It has a fullproof solution for uniquely identifying the device.

Solution 20 - Ios

You can use

NSString *sID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

Which is unique for the device in all application.

Solution 21 - Ios

A working way to get UDID:

  1. Launch a web server inside the app with two pages: one should return specially crafted MobileConfiguration profile and another should collect UDID. More info here, here and here.
  2. You open the first page in Mobile Safari from inside the app and it redirects you to Settings.app asking to install configuration profile. After you install the profile, UDID is sent to the second web page and you can access it from inside the app. (Settings.app has all necessary entitlements and different sandbox rules).

An example using RoutingHTTPServer:

import UIKit
import RoutingHTTPServer

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var bgTask = UIBackgroundTaskInvalid
    let server = HTTPServer()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        application.openURL(NSURL(string: "http://localhost:55555")!)
        return true
    }

    func applicationDidEnterBackground(application: UIApplication) {
        bgTask = application.beginBackgroundTaskWithExpirationHandler() {
            dispatch_async(dispatch_get_main_queue()) {[unowned self] in
                application.endBackgroundTask(self.bgTask)
                self.bgTask = UIBackgroundTaskInvalid
            }
        }
    }
}

class HTTPServer: RoutingHTTPServer {
    override init() {
        super.init()
        setPort(55555)
        handleMethod("GET", withPath: "/") {
            $1.setHeader("Content-Type", value: "application/x-apple-aspen-config")
            $1.respondWithData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("udid", ofType: "mobileconfig")!)!)
        }
        handleMethod("POST", withPath: "/") {
            let raw = NSString(data:$0.body(), encoding:NSISOLatin1StringEncoding) as! String
            let plistString = raw.substringWithRange(Range(start: raw.rangeOfString("<?xml")!.startIndex,end: raw.rangeOfString("</plist>")!.endIndex))
            let plist = NSPropertyListSerialization.propertyListWithData(plistString.dataUsingEncoding(NSISOLatin1StringEncoding)!, options: .allZeros, format: nil, error: nil) as! [String:String]
            
            let udid = plist["UDID"]! 
            println(udid) // Here is your UDID!
            
            $1.statusCode = 200
            $1.respondWithString("see https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html")
        }
        start(nil)
    }
}

Here are the contents of udid.mobileconfig:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadContent</key>
        <dict>
            <key>URL</key>
            <string>http://localhost:55555</string>
            <key>DeviceAttributes</key>
            <array>
                <string>IMEI</string>
                <string>UDID</string>
                <string>PRODUCT</string>
                <string>VERSION</string>
                <string>SERIAL</string>
            </array>
        </dict>
        <key>PayloadOrganization</key>
        <string>udid</string>
        <key>PayloadDisplayName</key>
        <string>Get Your UDID</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadUUID</key>
        <string>9CF421B3-9853-9999-BC8A-982CBD3C907C</string>
        <key>PayloadIdentifier</key>
        <string>udid</string>
        <key>PayloadDescription</key>
        <string>Install this temporary profile to find and display your current device's UDID. It is automatically removed from device right after you get your UDID.</string>
        <key>PayloadType</key>
        <string>Profile Service</string>
    </dict>
</plist>

The profile installation will fail (I didn't bother to implement an expected response, see documentation), but the app will get a correct UDID. And you should also sign the mobileconfig.

Solution 22 - Ios

For Swift 3.0 please use below code.

let deviceIdentifier: String = (UIDevice.current.identifierForVendor?.uuidString)!
NSLog("output is : %@", deviceIdentifier)

Solution 23 - Ios

Apple has added a new framework in iOS 11 called DeviceCheck which will help you to get the unique identifier very easily. Read this form more information. https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d

Solution 24 - Ios

If someone stumble upon to this question, when searching for an alternative. I have followed this approach in IDManager class, This is a collection from different solutions. KeyChainUtil is a wrapper to read from keychain. You can also use the hashed MAC address as a kind of unique ID.

/*	Apple confirmed this bug in their system in response to a Technical Support Incident 
    request. They said that identifierForVendor and advertisingIdentifier sometimes 
    returning all zeros can be seen both in development builds and apps downloaded over the 
    air from the App Store. They have no work around and can't say when the problem will be fixed. */
#define kBuggyASIID				@"00000000-0000-0000-0000-000000000000"

+ (NSString *) getUniqueID {
	if (NSClassFromString(@"ASIdentifierManager")) {
		NSString * asiID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
		if ([asiID compare:kBuggyASIID] == NSOrderedSame) {
			NSLog(@"Error: This device return buggy advertisingIdentifier.");
			return [IDManager getUniqueUUID];
		} else {
			return asiID;
		}
		
	} else {
		return [IDManager getUniqueUUID];
	}
}


+ (NSString *) getUniqueUUID {
	NSError * error;
	NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser	andServiceName:kIdOgBetilngService error:&error];
	if (error) {
		NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
		return nil;
	}
	if (!uuid) {
		DLog(@"No UUID found. Creating a new one.");
		uuid = [IDManager GetUUID];
		uuid = [Util md5String:uuid];
		[KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
		if (error) {
			NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
			return nil;
		}
	}
	return uuid;
}

/* NSUUID is after iOS 6. */
+ (NSString *)GetUUID
{
	CFUUIDRef theUUID = CFUUIDCreate(NULL);
	CFStringRef string = CFUUIDCreateString(NULL, theUUID);
	CFRelease(theUUID);
	return [(NSString *)string autorelease];
}

#pragma mark - MAC address
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Last fallback for unique identifier
+ (NSString *) getMACAddress
{
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Error: Memory allocation error\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2\n");
        free(buf); // Thanks, Remy "Psy" Demerest
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
	
    free(buf);
    return outstring;
}

+ (NSString *) getHashedMACAddress
{
	NSString * mac = [IDManager getMACAddress];
	return [Util md5String:mac];
}

+ (NSString *)md5String:(NSString *)plainText
{
	if(plainText == nil || [plainText length] == 0)
        return nil;
    
    const char *value = [plainText UTF8String];
    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(value, strlen(value), outputBuffer);
    
    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
        [outputString appendFormat:@"%02x",outputBuffer[count]];
    }
    NSString * retString = [NSString stringWithString:outputString];
	[outputString release];
	return retString;
}

Solution 25 - Ios

+ (NSString *) getUniqueUUID {
    NSError * error;
    NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error];
    if (error) {
    NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
    return nil;
    }
    if (!uuid) {
        DLog(@"No UUID found. Creating a new one.");
        uuid = [IDManager GetUUID];
        uuid = [Util md5String:uuid];
        [KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
        if (error) {
            NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
            return nil;
        }
    }
    return uuid;
}

Solution 26 - Ios

We can use identifierForVendor for ios7,

-(NSString*)uniqueIDForDevice
{
    NSString* uniqueIdentifier = nil;
    if( [UIDevice instancesRespondToSelector:@selector(identifierForVendor)] ) { // >=iOS 7
        uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    } else { //<=iOS6, Use UDID of Device       
            CFUUIDRef uuid = CFUUIDCreate(NULL);
            //uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);- for non- ARC
            uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));// for ARC
            CFRelease(uuid);
         }
    }
return uniqueIdentifier;
}

--Important Note ---

UDID and identifierForVendor are different:---

1.) On uninstalling  and reinstalling the app identifierForVendor will change.

2.) The value of identifierForVendor remains the same for all the apps installed from the same vendor on the device.

3.) The value of identifierForVendor also changes for all the apps if any of the app (from same vendor) is reinstalled.

Solution 27 - Ios

Apple has hidden the UDID from all public APIs, starting with iOS 7. Any UDID that begins with FFFF is a fake ID. The "Send UDID" apps that previously worked can no longer be used to gather UDID for test devices. (sigh!)

The UDID is shown when a device is connected to XCode (in the organizer), and when the device is connected to iTunes (although you have to click on 'Serial Number' to get the Identifier to display.

If you need to get the UDID for a device to add to a provisioning profile, and can't do it yourself in XCode, you will have to walk them through the steps to copy/paste it from iTunes.

https://stackoverflow.com/questions/19032162/is-there-a-way-since-ios-7s-release-to-get-the-udid-without-using-itunes-on-a

Solution 28 - Ios

I had got some issue too, and solution is simple:

    // Get Bundle Info for Remote Registration (handy if you have more than one app)
    NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    
    
    // Get the users Device Model, Display Name, Unique ID, Token & Version Number
    UIDevice *dev = [UIDevice currentDevice];
    NSString *deviceUuid=[dev.identifierForVendor  UUIDString];
    
    NSString *deviceName = dev.name;

Solution 29 - Ios

A not perfect but one of the best and closest alternative to UDID (in Swift using iOS 8.1 and Xcode 6.1):

Generating a random UUID

let strUUID: String = NSUUID().UUIDString

And use KeychainWrapper library:

Add a string value to keychain:

let saveSuccessful: Bool = KeychainWrapper.setString("Some String", forKey: "myKey")

Retrieve a string value from keychain:

let retrievedString: String? = KeychainWrapper.stringForKey("myKey")

Remove a string value from keychain:

let removeSuccessful: Bool = KeychainWrapper.removeObjectForKey("myKey")

This solution uses the keychain, thus the record stored in the keychain will be persisted, even after the app is uninstalled and reinstalled. The only way of deleting this record is to Reset all contents and settings of the device. That is why I mentioned that this solution of substitution is not perfect but stays one of the best solution of replacement for UDID on iOS 8.1 using Swift.

Solution 30 - Ios

NSLog(@"%@",[[UIDevice currentDevice]identifierForVendor]);

Solution 31 - Ios

Dont use these libraries - libOmnitureAppMeasurement, It does use uniqueIdentifier which apple doesnt support anymore

Solution 32 - Ios

Little hack for you:

/**
 @method uniqueDeviceIdentifier
 @abstract 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 
 be tied to a user account. [UIDevice Class Reference]
 @return An 1-way hashed identifier unique to this device.
 */
+ (NSString *)uniqueDeviceIdentifier {    	
	NSString *systemId = nil;
	// We collect it as long as it is available along with a randomly generated ID.
	// This way, when this becomes unavailable we can map existing users so the
	// new vs returning counts do not break.
    if (([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0f)) {
		SEL udidSelector = NSSelectorFromString(@"uniqueIdentifier");
		if ([[UIDevice currentDevice] respondsToSelector:udidSelector]) {
			systemId = [[UIDevice currentDevice] performSelector:udidSelector];
		}
	}
    else {
        systemId = [NSUUID UUID];
    }
	return systemId;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOliver PearmainView Question on Stackoverflow
Solution 1 - IosDarkDustView Answer on Stackoverflow
Solution 2 - IosSerhii MamontovView Answer on Stackoverflow
Solution 3 - IosMatView Answer on Stackoverflow
Solution 4 - IosyturView Answer on Stackoverflow
Solution 5 - IosSamir JwarchanView Answer on Stackoverflow
Solution 6 - IosdiadyneView Answer on Stackoverflow
Solution 7 - IosylechelleView Answer on Stackoverflow
Solution 8 - IosMathew WatersView Answer on Stackoverflow
Solution 9 - IosNateView Answer on Stackoverflow
Solution 10 - IosAshvin AView Answer on Stackoverflow
Solution 11 - IoschownView Answer on Stackoverflow
Solution 12 - IosSachinVsSachinView Answer on Stackoverflow
Solution 13 - IosToastorView Answer on Stackoverflow
Solution 14 - IosMahendra LiyaView Answer on Stackoverflow
Solution 15 - IosKomposrView Answer on Stackoverflow
Solution 16 - IossantifyView Answer on Stackoverflow
Solution 17 - IosGrzegorz KrukowskiView Answer on Stackoverflow
Solution 18 - IosDShahView Answer on Stackoverflow
Solution 19 - IosSantosh BotreView Answer on Stackoverflow
Solution 20 - IosDhavalView Answer on Stackoverflow
Solution 21 - IosbzzView Answer on Stackoverflow
Solution 22 - IosGaneshView Answer on Stackoverflow
Solution 23 - IosSantosh BotreView Answer on Stackoverflow
Solution 24 - IoskarimView Answer on Stackoverflow
Solution 25 - Iosmahesh chowdaryView Answer on Stackoverflow
Solution 26 - IosHDdeveloperView Answer on Stackoverflow
Solution 27 - IosPreetView Answer on Stackoverflow
Solution 28 - IosAhmet Kazim GünayView Answer on Stackoverflow
Solution 29 - IosKing-WizardView Answer on Stackoverflow
Solution 30 - IosgargView Answer on Stackoverflow
Solution 31 - IosNagarjunaView Answer on Stackoverflow
Solution 32 - IosdigipeopleView Answer on Stackoverflow