Как получить уникальный идентификатор устройства в Swift?

186

Как я могу получить уникальный идентификатор устройства в Swift?

Мне нужен идентификатор для использования в базе данных и в качестве ключа API для моего веб-сервиса в моем социальном приложении. Что-то, чтобы отслеживать ежедневное использование этого устройства и ограничивать его запросы к базе данных.

Благодарность!

Пользователь
источник

Ответы:

394

Вы можете использовать это (Swift 3):

UIDevice.current.identifierForVendor!.uuidString

Для более старых версий:

UIDevice.currentDevice().identifierForVendor

или если вам нужна строка:

UIDevice.currentDevice().identifierForVendor!.UUIDString


Больше не существует способа однозначно идентифицировать устройство после того, как пользователь удалил приложение (я). В документации говорится:

Значение этого свойства остается неизменным, пока приложение (или другое приложение от того же поставщика) установлено на устройстве iOS. Значение изменяется, когда пользователь удаляет все приложения этого поставщика с устройства и впоследствии переустанавливает одно или несколько из них.


Вы также можете прочитать эту статью Мэтта Томпсона для получения более подробной информации:
http://nshipster.com/uuid-udid-unique-identifier/

Обновление для Swift 4.1 , вам нужно будет использовать:

UIDevice.current.identifierForVendor?.uuidString
Атомикс
источник
возможно, добавить .UUIDString, чтобы его можно было отправить на сервер?
Даниэль Галаско
2
Ага. Я подумал, что это очевидная вещь, но я включил ее в ответ.
Atomix
20
После удаления приложения этот номер больше не тот. Есть ли способ отслеживать устройство даже после удаления приложения?
jmcastel
5
Лучший вопрос: если он будет удален после удаления, как вы удалите их учетную запись на своем сервере, когда идентификатор больше не используется?
Джейсон Джи
2
@UmairAfzal В симуляторе много чего не работает. Вы пробовали это на реальном устройстве?
Atomix
10

Вы можете использовать общедоступное свойство identifierForVendor, присутствующее в классе UIDevice

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

ИЗМЕНИТЬ Swift 3:

UIDevice.current.identifierForVendor!.uuidString

КОНЕЦ РЕДАКТИРОВАНИЯ

Снимок экрана для иерархии свойств

Джайпракаш Дубей
источник
3
Это всего лишь копия ответа @Atomix
Эшли Миллс
10

Для Swift 3.X последний рабочий код, простота использования;

   let deviceID = UIDevice.current.identifierForVendor!.uuidString
   print(deviceID)
SwiftDeveloper
источник
3
Это меняется каждый раз при использовании удаления и повторной установки приложения.
iPeter
7
Это всего лишь копия ответов @Atomix & JayprakasDubey
Эшли Миллс,
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" ...
    }
}

Типичное использование:

Как правило, вы используете API-интерфейсы DeviceCheck, чтобы убедиться, что новый пользователь еще не активировал предложение под другим именем пользователя на том же устройстве.

Действия сервера требуют:

См. WWDC 2017 - Сессия 702

больше из статьи Сантоша Ботре - Уникальный идентификатор для устройств iOS

Ваш ассоциированный сервер объединяет этот токен с ключом аутентификации, который вы получаете от Apple, и использует результат для запроса доступа к битам для каждого устройства.

iluvatar_GR
источник
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

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")!)
n.by.n
источник
3
Бесполезно, если пользователь удаляет приложение, потому что userdefaults также удаляются с удалением приложения.
Рехан Али
0

Значение identifierForVendor изменяется, когда пользователь удаляет все приложения этого поставщика с устройства, если вы хотите сохранить уникальный идентификатор даже для последующих новых установок, вы можете попробовать использовать следующую функцию

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 - это настраиваемые методы, которые вам нужно реализовать, я не включил эти определения, думая, что не увеличивает размер ответа.
Шихаб
Сохраняются ли значения, хранящиеся в связке ключей, после удаления приложения?
Anees
1
@Anees, вы правы, мой ответ недействителен для iOS 10.3 Beta 2, он автоматически удаляет элементы связки ключей после удаления приложения, если нет общих приложений. Итак, наконец, это будет то же поведение, что и у метода identifierForVendor.
Шихаб
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)
        }
    }
}
Джоуи
источник
-18

Я пробовал с

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

вместо

let UUID = NSUUID().UUIDString

и это работает.

Мэтт
источник
32
NSUUID (). UUIDString будет выдавать вам новую строку каждый раз
Эрик,