Question 1: Under what circumstances does the value of [[UIDevice currentDevice] identifierForVendor].UUIDString change?
[[UIDevice currentDevice] identifierForVendor].UUIDString
is a unique identifier (UUID) used to identify a device that is invariant across devices for the same application vendor (i.e., a collection of applications from the same developer). However, there are a number of circumstances that can cause this identifier to change:
situation causes the identifierForVendor to change:
-
Application uninstallation and reinstallation: When all apps from the same vendor are uninstalled on the device and any of them are reinstalled, a new
identifierForVendor
. This means that if the user completely clears your app and reinstalls it, it will get a new value. -
Restoring the device to factory settings: If the device is restored to factory settings, it will also generate a new
identifierForVendor
。
Beyond that.identifierForVendor
It will not change due to usual operations on the device (e.g., rebooting the device, software updates, etc.).
Benefits of Storing to Keychain
Keychain is a system-level service for securely storing sensitive information and is suitable for storing important data such as passwords, certificates and encryption keys. PuttingidentifierForVendor
There are some advantages to storing to Keychain:
- durability: The data stored in Keychain is not deleted even if the user deletes the application. When the user reinstalls the application, the data can be recovered from Keychain.
- safety: Keychain provides highly secure storage that protects sensitive data much better than ordinary file storage.
- Cross-application sharing: With proper configuration, applications from the same vendor can share data in Keychain.
Here's what willidentifierForVendor
Sample code for storing to Keychain:
#import <Security/>
- (void)storeIdentifierForVendorInKeychain {
NSString *uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *key = @"";
// Delete the previously stored UUID
[self deleteUUIDFromKeychain:key];
NSData *uuidData = [uuid dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassGenericPassword,
(id)kSecAttrAccount: key,
(id)kSecValueData: uuidData,
};
OSStatus status = SecItemAdd((CFDictionaryRef)query, NULL);
if (status == errSecSuccess) {
NSLog(@"UUID stored successfully.");
} else {
NSLog(@"Error storing UUID: %d", (int)status);
}
}
- (NSString *)retrieveUUIDFromKeychain {
NSString *key = @"";
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassGenericPassword,
(id)kSecAttrAccount: key,
(id)kSecReturnData: (id)kCFBooleanTrue,
};
CFDataRef dataRef = NULL;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&dataRef);
if (status == errSecSuccess) {
NSData *resultData = (__bridge NSData *)dataRef;
NSString *uuid = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
CFRelease(dataRef);
return uuid;
} else {
NSLog(@"Error retrieving UUID: %d", (int)status);
return nil;
}
}
- (void)deleteUUIDFromKeychain:(NSString *)key {
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassGenericPassword,
(id)kSecAttrAccount: key,
};
OSStatus status = SecItemDelete((CFDictionaryRef)query);
if (status == errSecSuccess) {
NSLog(@"UUID deleted successfully.");
} else {
NSLog(@"Error deleting UUID: %d", (int)status);
}
}
Steps:
-
Storing UUIDs: Use
storeIdentifierForVendorInKeychain
method willidentifierForVendor
Stored in Keychain. -
Retrieve UUID: Use
retrieveUUIDFromKeychain
method retrieves the stored UUID from the Keychain. -
Delete UUID: Use
deleteUUIDFromKeychain
method deletes the stored UUID.
With these steps and methods, you can ensure that even if the app is deleted and reinstalled, you can recover from Keychain the previousidentifierForVendor
, keeping the UUID consistent.
Question 2: What are the circumstances under which the value will change when it is stored in Keychain?
Data stored in Keychain usually changes under some specific circumstances. The following are some of the major scenarios:
1. Restore Factory Settings
Restoring factory settings erases all data on the device, including application data, user files, system settings, and Keychain data. In this case, any values stored in the Keychain (e.g. identifiers, passwords, etc.) are deleted and cannot be recovered.
2. replacing firmware (on a mobile device)
Flashing usually refers to reinstalling the device's firmware or operating system. The flashing process also erases all data on the device, including the data in the Keychain. As a result, the values stored in the Keychain are deleted.
3. App is uninstalled
Unlike normal file storage, the data in Keychain is not deleted when the application is uninstalled. When the app is reinstalled, you can continue to access the previously stored Keychain data. However, if the user chooses to "Delete app's data" or cleans Keychain data using certain third-party tools, the associated stored values may be deleted.
4. equipment migration
In some cases, Keychain data is synchronized to a new device through an iCloud backup or device migration. If a user chooses not to migrate Keychain data (for example, chooses not to back up Keychain during a device migration), the values in the new device can change or be lost.
5. jailbreak device (computing)
Jailbreaking increases the risk of Keychain data being accessed, modified, or deleted by third-party tools. Although jailbreaking itself does not directly change the values in the Keychain, applications and actions taken after jailbreaking may affect its data integrity and may result in Keychain data being tampered with or erased.
6. application-specific operation
If the application actively deletes or updates data in the Keychain under certain conditions (e.g., user logs out, gets a new account, reinstalls, etc.), this can also result in changes to the associated values. Example:
- (void)deleteIdentifierInKeychain {
NSString *key = @"";
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassGenericPassword,
(id)kSecAttrAccount: key,
};
OSStatus status = SecItemDelete((CFDictionaryRef)query);
if (status == errSecSuccess) {
NSLog(@"UUID deleted successfully.");
} else {
NSLog(@"Error deleting UUID: %d", (int)status);
}
}
7. User-initiated removal of Keychain
Users can actively choose to purge specific Keychain data through certain tools or settings, which can result in the deletion or change of stored values.
Frequently Asked Questions:
-
Uninstalling and reinstalling applications:
- No restoration of factory settings: Reinstalling the application usually does not affect Keychain data.
- Restore factory settings or reset all settings: Keychain data is deleted.
-
Device Switching:
- If the user does not backup or restore the Keychain data during the device switchover process, the new Keychain data will be regenerated.
In short, although Keychain storage provides a relatively persistent storage mechanism, stored values may change or be purged under the following circumstances:
- Restore factory settings or brush.
- Device migration without synchronizing Keychain data.
- Jailbreak-induced data tampering or erasure.
- The Keychain data is cleared either by the application itself or by the user.