Trong phát triển ứng dụng iOS, việc xác định và phân biệt thiết bị người dùng là yêu cầu nền tảng cho nhiều chức năng như phân tích hành vi, quảng cáo cá nhân hóa, kiểm soát bản quyền hoặc đồng bộ dữ liệu. Tuy nhiên, do chính sách bảo mật ngày càng nghiêm ngặt của Apple, các cơ chế định danh đã thay đổi đáng kể qua từng phiên bản hệ điều hành. Dưới đây là tổng quan kỹ thuật về các loại định danh phổ biến, kèm đặc điểm hoạt động, giới hạn sử dụng và cách triển khai thực tế.
1. UDID (Unique Device Identifier)
UDID từng là chuỗi 40 ký tự duy nhất đại diện cho mỗi thiết bị iOS, được sử dụng rộng rãi trong các ứng dụng yêu cầu ràng buộc "một thiết bị – một tài khoản". Từ iOS 5 trở đi, Apple đã chặn hoàn toàn khả năng truy cập UDID qua API công khai nhằm tăng cường bảo vệ quyền riêng tư. Hiện nay, không còn cách nào lập trình để lấy giá trị này trong môi trường runtime — mọi thao tác chỉ có thể thực hiện bên ngoài ứng dụng, ví dụ:
- Qua Xcode: Kết nối thiết bị → Window → Devices and Simulators → Chọn thiết bị → sao chép giá trị tại mục Identifier.
- Thông qua dịch vụ bên thứ ba như蒲公英 (PGYER): Cài đặt profile mô phỏng để hiển thị thông tin thiết bị trong trình duyệt, sau đó sao chép phần UDID từ giao diện web.
2. UUID (Universally Unique Identifier)
UUID là định danh được sinh ngẫu nhiên bởi ứng dụng, không phụ thuộc vào phần cứng hay hệ thống. Mỗi lần gọi hàm tạo mới sẽ sinh ra một giá trị khác nhau — do đó, để đảm bảo tính nhất quán giữa các phiên cài đặt, cần lưu trữ giá trị này vào Keychain (không phải UserDefaults), vì Keychain tồn tại độc lập với vòng đời ứng dụng.
Dưới đây là hàm triển khai chuẩn để tạo và lưu UUID bền vững:
// Tạo UUID duy nhất cho ứng dụng
+ (NSString *)generatePersistentAppUUID {
NSString *key = @"com.example.app.uuid";
NSString *savedUUID = [self readFromKeychain:key];
if (!savedUUID || savedUUID.length == 0) {
CFUUIDRef uuidRef = CFUUIDCreate(NULL);
CFStringRef uuidStrRef = CFUUIDCreateString(NULL, uuidRef);
savedUUID = (__bridge_transfer NSString *)uuidStrRef;
CFRelease(uuidRef);
[self writeToKeychain:key value:savedUUID];
}
return savedUUID;
}
Lưu ý: Giá trị UUID thay đổi khi thiết bị được khôi phục cài đặt gốc (Erase All Content and Settings), nhưng giữ nguyên sau khi gỡ cài đặt và cài lại ứng dụng — miễn là Keychain chưa bị xóa.
3. IDFA (Identifier for Advertisers)
IDFA là định danh hệ thống dành riêng cho mục đích quảng cáo, được quản lý toàn cục bởi iOS và chia sẻ giữa tất cả ứng dụng trên cùng một thiết bị. Giá trị này có thể bị reset bởi người dùng thông qua hai đường dẫn:
- Cài đặt → Chung → Đặt lại → Đặt lại vị trí & quyền riêng tư
- Cài đặt → Quảng cáo → Đặt lại ID quảng cáo
Từ iOS 14 trở đi, IDFA mặc định bị tắt trừ khi người dùng chủ động bật tùy chọn Cho phép theo dõi trong mục Quảng cáo → Cá nhân hóa quảng cáo. Do tỷ lệ chấp thuận rất thấp (dưới 1% ở nhiều khu vực), IDFA ngày càng kém khả thi làm định danh chính cho phân tích người dùng.
Ví dụ truy vấn IDFA:
#import <AdSupport/AdSupport.h>
- (NSString *)fetchAdvertisingIdentifier {
ASIdentifierManager *manager = [ASIdentifierManager sharedManager];
if ([manager isAdvertisingTrackingEnabled]) {
return [[manager advertisingIdentifier] UUIDString];
}
return nil;
}
Chú ý: Không nên sử dụng IDFA làm khóa chính trong hệ thống nghiệp vụ — vì nó có thể trả về nil, hoặc thay đổi bất kỳ lúc nào do hành động người dùng.
4. IDFV (Identifier for Vendor)
IDFV là định danh cấp nhà cung cấp (vendor), được hệ thống sinh dựa trên phần tiền tố DNS đảo ngược của Bundle ID (ví dụ: com.company.app1 và com.company.app2 chia sẻ cùng một IDFV). Đây là lựa chọn tối ưu cho phân tích hành vi nội bộ — vì giá trị luôn tồn tại và ổn định miễn là thiết bị còn chứa ít nhất một ứng dụng cùng vendor.
Cách lấy giá trị:
NSString *vendorID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
Hành vi đặc trưng:
- Giá trị luôn khác nhau giữa các vendor.
- Cùng vendor → cùng IDFV trên mọi ứng dụng của vendor đó trên cùng thiết bị.
- Nếu xóa toàn bộ ứng dụng của vendor → IDFV sẽ bị reset khi cài lại.
- Không bị ảnh hưởng bởi khởi động lại thiết bị, nhưng sẽ thay đổi khi khôi phục cài đặt gốc.
5. Các định danh hệ thống khác (không còn khả dụng)
Một số định danh phần cứng như IMEI, IMSI và MAC Address từng được dùng để nhận diện thiết bị ở mức hạ tầng, nhưng đã bị Apple loại bỏ khỏi API công khai từ các phiên bản iOS tương ứng:
- IMEI: Bị chặn từ iOS 5 do rủi ro bảo mật cao.
- IMSI: Không thể truy cập trực tiếp từ ứng dụng iOS.
- MAC Address: Từ iOS 7, hệ thống trả về địa chỉ giả (
02:00:00:00:00:00) thay vì giá trị thật.
Tất cả các giá trị này đều không còn phù hợp cho logic nghiệp vụ trên nền tảng App Store — việc cố gắng thu thập chúng có thể dẫn đến từ chối khi xét duyệt.