如何在Swift中获得唯一的设备ID?


180

如何在Swift中获取设备的唯一ID?

我需要一个ID才能在数据库中使用,并作为我的社交应用程序中Web服务的API密钥。可以跟踪该设备日常使用并将其查询限制在数据库中的东西。

谢谢!

Answers:


385

您可以使用此(快速3):

UIDevice.current.identifierForVendor!.uuidString

对于旧版本:

UIDevice.currentDevice().identifierForVendor

或者如果您想要一个字符串:

UIDevice.currentDevice().identifierForVendor!.UUIDString


用户卸载应用后,不再有一种唯一标识设备的方法。该文档说:

当该应用程序(或同一供应商的另一个应用程序)安装在iOS设备上时,此属性中的值保持不变。当用户从设备中删除该供应商的所有应用程序,然后重新安装其中一个或多个应用程序时,该值将更改。


您可能还想阅读Mattt Thompson的这篇文章,以了解更多详细信息:http ://nshipster.com/uuid-udid-unique-identifier/

Swift 4.1的更新,您将需要使用:

UIDevice.current.identifierForVendor?.uuidString

也许添加.UUIDString以便可以将其实际发送到服务器?
Daniel Galasko 2014年

2
对。我认为这是显而易见的事情,但我将其包括在答案中。
Atomix 2014年

19
应用程序卸载后,该数字不再相同。即使在应用卸载后,有没有办法跟踪设备?
jmcastel 2014年

5
更好的问题是,如果在卸载后将其删除,那么当该ID不再使用时,如何在服务器上删除其帐户?
杰森·G

2
@UmairAfzal许多事情在模拟器中不起作用。您是否在真实设备上尝试过?
Atomix

10

您可以使用UIDevice类中存在的identifierForVendor公共属性

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

编辑 Swift 3:

UIDevice.current.identifierForVendor!.uuidString

结束编辑

属性层次结构的屏幕截图


3
这只是@Atomix答案的副本
Ashley Mills

10

对于Swift 3.X最新工作代码,易于使用;

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

3
每当使用卸载并再次安装该应用程序时,这种情况都会改变。
iPeter

7
这只是@Atomix和JayprakasDubey的答案的副本
Ashley Mills,

10

您可以使用devicecheck(在Swift 4中) Apple文档

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" ...
    }
}

典型用法:

通常,您使用DeviceCheck API来确保新用户尚未在同一设备上以其他用户名兑换优惠。

服务器操作需要:

请参阅WWDC 2017 —会话702

Santosh Botre文章中的更多内容-iOS设备的唯一标识符

您关联的服务器将此令牌与您从Apple收到的身份验证密钥结合在一起,并使用结果请求访问每设备位。


1
如果我正确理解,则使用DCDevice.generateToken()执行令牌生成,并且每次调用都会生成一个唯一的随机device_token。因此,device_token不是持久性的,而是短暂的。我不了解的是服务器如何将临时令牌与设备关联。
user1118764

@ user1118764“设置两位-应用程序服务器将负责共享此令牌并设置位值。” 在这里阅读更多medium.com/@santoshbotre01/...从官方文档和这里developer.apple.com/documentation/devicecheck/...和702届developer.apple.com/videos/play/wwdc2017/702
iluvatar_GR

1

斯威夫特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
用户删除应用程序是没有用的,因为userdefaults也会在卸载应用程序时被删除。
Rehan Ali,

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

1
请评论您的代码和/或提供详细信息,并说明如何解决发布的问题。
RyanNerd

-1
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)
        }
    }
}

-1

当用户从设备上删除该供应商的所有应用程序时,identifierForVendor的值更改,如果您甚至在以后的全新安装中也要保留唯一的ID,则可以尝试使用以下功能

func vendorIdentifierForDevice()->String {
    //Get common part of Applicatoin Bundle ID, Note : getCommonPartOfApplicationBundleID is to be defined.
    let commonAppBundleID = getCommonPartOfApplicationBundleID()
    //Read from KeyChain using bunndle ID, Note : readFromKeyChain is to be defined.
    if let vendorID = readFromKeyChain(commonAppBundleID) {
        return vendorID
    } else {
        var vendorID = NSUUID().uuidString
        //Save to KeyChain using bunndle ID, Note : saveToKeyChain is to be defined.
        saveToKeyChain(commonAppBundleID, vendorID)
        return vendorID
    }
}

谁对此投票投了反对票,请您解释一下为什么对此投反对票?getCommonPartOfApplicationBundleID(),readFromKeyChain,saveToKeyChain是您需要实现的自定义方法,我没有考虑那些不增加答案大小的定义。
Shihab

卸载应用程序后,存储在钥匙串中的值是否仍然存在?
Anees

1
@Anees,您是正确的,我的答案在iOS 10.3 Beta 2中无效,如果没有共享应用程序,则它会在应用程序卸载后自动删除钥匙串项。因此,最终它将与identifierForVendor方法相同。
Shihab

-17

我尝试过

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

代替

let UUID = NSUUID().UUIDString

而且有效。


30
NSUUID()。UUIDString每次都会为您提供一个新字符串
Eric
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.