Làm cách nào để có được ID thiết bị duy nhất trong Swift?


181

Làm cách nào tôi có thể nhận được ID thiết bị duy nhất trong Swift?

Tôi cần một ID để sử dụng trong cơ sở dữ liệu và làm khóa API cho dịch vụ web của mình trong ứng dụng xã hội. Một cái gì đó để theo dõi các thiết bị này sử dụng hàng ngày và giới hạn các truy vấn của nó vào cơ sở dữ liệu.

Cảm ơn!

Câu trả lời:


386

Bạn có thể sử dụng cái này (Swift 3):

UIDevice.current.identifierForVendor!.uuidString

Đối với phiên bản cũ hơn:

UIDevice.currentDevice().identifierForVendor

hoặc nếu bạn muốn một chuỗi:

UIDevice.currentDevice().identifierForVendor!.UUIDString


Không còn cách nào để xác định duy nhất một thiết bị sau khi người dùng gỡ cài đặt (các) ứng dụng. Các tài liệu nói:

Giá trị trong thuộc tính này vẫn giữ nguyên trong khi ứng dụng (hoặc ứng dụng khác từ cùng một nhà cung cấp) được cài đặt trên thiết bị iOS. Giá trị thay đổi khi người dùng xóa tất cả các ứng dụng của nhà cung cấp đó khỏi thiết bị và sau đó cài đặt lại một hoặc nhiều trong số chúng.


Bạn cũng có thể muốn đọc bài viết này của Mattt Thompson để biết thêm chi tiết:
http://nshipster.com/uuid-udid-unique-identifier/

Cập nhật cho Swift 4.1 , bạn sẽ cần sử dụng:

UIDevice.current.identifierForVendor?.uuidString

có lẽ thêm .UUIDString để nó thực sự có thể được gửi đến máy chủ?
Daniel Galasko

2
Vâng Tôi nghĩ rằng đó là điều rõ ràng phải làm, nhưng tôi đã đưa nó vào câu trả lời.
Atomix

19
Sau khi gỡ cài đặt ứng dụng, con số này không còn như trước nữa. Có cách nào để theo dõi một thiết bị ngay cả sau khi gỡ cài đặt ứng dụng không?
jmcastel

5
câu hỏi tốt hơn là, nếu nó bị xóa sau khi gỡ cài đặt, làm thế nào để bạn xóa tài khoản của họ trên máy chủ của bạn khi ID không còn được sử dụng?
Jason G

2
@UmairAfzal Rất nhiều thứ không hoạt động trong trình giả lập. Bạn đã thử nó trên thiết bị thực sự?
Atomix

10

Bạn có thể sử dụng định danh tài sản công cộngForVendor có trong lớp UIDevice

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

EDIT Swift 3:

UIDevice.current.identifierForVendor!.uuidString

EDIT KẾT THÚC

Ảnh chụp màn hình cho phân cấp tài sản


3
Đây chỉ là một bản sao của câu trả lời @Atomix
Ashley Mills

10

Đối với Swift 3.X Mã làm việc mới nhất, dễ dàng sử dụng;

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

3
Điều này thay đổi bất cứ khi nào sử dụng gỡ cài đặt và cài đặt lại ứng dụng.
iPeter

7
Đây chỉ là bản sao câu trả lời của @Atomix & JayprakasDubey
Ashley Mills

10

Bạn có thể sử dụng tài liệu devicecheck (trong Swift 4)

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

Cách sử dụng điển hình:

Thông thường, bạn sử dụng API DeviceCheck để đảm bảo rằng người dùng mới chưa đổi phiếu mua hàng dưới một tên người dùng khác trên cùng một thiết bị.

Nhu cầu hành động của máy chủ:

Xem WWDC 2017 - Phiên 702

thêm từ bài viết của Santosh Botre - Mã định danh duy nhất cho các thiết bị iOS

Máy chủ được liên kết của bạn kết hợp mã thông báo này với khóa xác thực mà bạn nhận được từ Apple và sử dụng kết quả để yêu cầu quyền truy cập vào các bit trên mỗi thiết bị.


1
Nếu tôi hiểu chính xác, việc tạo mã thông báo được thực hiện bằng DCDevice.generateToken () và mỗi cuộc gọi sẽ tạo ra một device_token duy nhất, ngẫu nhiên. Do đó, device_token không tồn tại lâu, nhưng phù du. Điều tôi không hiểu là làm thế nào máy chủ có thể liên kết mã thông báo phù du với thiết bị.
dùng1118764

@ user1118764 "Đặt hai bit - Máy chủ ứng dụng sẽ chịu trách nhiệm chia sẻ mã thông báo này và đặt giá trị bit." đọc thêm ở đây Medium.com/@santoshbotre01/ và cũng ở đây từ nhà phát triển tài liệu chính thức.apple.com / document / devicecheck / trộm và 702 phiên developer.apple.com/ideo/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")!)

2
Sẽ vô ích nếu người dùng xóa ứng dụng vì lỗi người dùng cũng bị xóa khi gỡ cài đặt ứng dụng.
Rehan Ali

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

1
Vui lòng nhận xét mã của bạn và / hoặc cung cấp chi tiết và giải thích về cách giải quyết câu hỏi được đăng.
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

Giá trị của mã định danhForVendor thay đổi khi người dùng xóa tất cả các ứng dụng của nhà cung cấp đó khỏi thiết bị, nếu bạn muốn giữ ID duy nhất ngay cả cho các cài đặt mới tiếp theo, bạn có thể thử sử dụng chức năng sau

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

Ai đã từng bỏ phiếu cho câu trả lời này, bạn có thể giải thích tại sao điều này lại bỏ phiếu không? getCommonPartOfApplicationBundleID (), readFromKeyChain, saveToKeyChain là các phương thức tùy chỉnh bạn cần thực hiện, tôi không bao gồm những suy nghĩ định nghĩa không làm tăng kích thước của câu trả lời.
Shihab

Các giá trị được lưu trữ trong móc khóa có tồn tại khi gỡ cài đặt ứng dụng không?
Anes

1
@Anees, bạn đúng là câu trả lời của tôi không hợp lệ từ iOS 10.3 Beta 2, nó tự động xóa các mục móc khóa sau khi gỡ cài đặt ứng dụng, nếu không có ứng dụng chia sẻ. Vì vậy, cuối cùng nó sẽ có hành vi tương tự như định danhForVendor methid.
Shihab

-18

Tôi đã thử với

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

thay thế

let UUID = NSUUID().UUIDString

Và nó hoạt động.


30
NSUUID (). UUIDString sẽ cung cấp cho bạn một chuỗi mới mỗi lần
Eric
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.