iOS开发基础149-由UUIDString引发的思考
问题1:[[UIDevice currentDevice] identifierForVendor].UUIDString什么情况下值会变化?
[[UIDevice currentDevice] identifierForVendor].UUIDString 是一个用于标识设备的唯一标识符(UUID),针对同一应用程序供应商(即同一开发者的应用程序集合),在设备上不变。然而,有一些情况会导致这个标识符发生变化:
情况导致 identifierForVendor 变化:
应用卸载和重装:当设备上来自同一供应商的所有应用程序都被卸载,再重新安装任意一个应用程序时,会生成新的
identifierForVendor。这意味着,如果用户完全清除你的应用并重新安装,它会获得一个新值。设备恢复出厂设置:如果设备被恢复出厂设置,也会生成新的
identifierForVendor。
除此之外,identifierForVendor 不会因为设备上的通常操作(如重启设备、软件更新等)而改变。
存储到 Keychain 的优势
Keychain 是一个安全存储敏感信息的系统级服务,适用于存储比如密码、证书和加密密钥等重要数据。把 identifierForVendor 存储到 Keychain 有一些优势:
- 持久性:即使用户删除了应用,Keychain 中存储的数据不会被删除。当用户重新安装应用时,可以从 Keychain 中恢复数据。
- 安全性:Keychain 提供了高安全性的存储方式,对敏感数据的保护比普通的文件存储要好得多。
- 跨应用共享:在适当的配置下,同一供应商的应用程序可以共享 Keychain 中的数据。
下面是将 identifierForVendor 存储到 Keychain 的示例代码:
#import <Security/Security.h>
- (void)storeIdentifierForVendorInKeychain {
NSString *uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *key = @"com.yourcompany.yourapp.identifierForVendor";
// 删除之前存储的 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 = @"com.yourcompany.yourapp.identifierForVendor";
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);
}
}
步骤:
- 存储 UUID:使用
storeIdentifierForVendorInKeychain方法将identifierForVendor存储到 Keychain 中。 - 检索 UUID:使用
retrieveUUIDFromKeychain方法从 Keychain 中检索存储的 UUID。 - 删除 UUID:使用
deleteUUIDFromKeychain方法删除存储的 UUID。
通过这些步骤和方法,你可以确保即使应用被删除和重新安装,也可以从 Keychain 中恢复先前的 identifierForVendor,保持UUID的一致性。
问题2:存储到 Keychain,什么情况下值会变化 ?
存储在 Keychain 中的数据通常在一些特定情况下会发生变化。以下是其中一些主要情形:
1. 恢复出厂设置
恢复出厂设置会清除设备上的所有数据,包括应用数据、用户文件、系统设置和 Keychain 数据。在这种情况下,Keychain 中存储的任何值(例如标识符、密码等)都会被删除并且无法恢复。
2. 刷机
刷机通常指的是重新安装设备的固件或操作系统。刷机过程也会清除设备上的所有数据,包括 Keychain 中的数据。因此,存储在 Keychain 中的值会被删除。
3. 应用被卸载
不同于普通的文件存储,Keychain 中的数据在应用被卸载时不会被删除。当应用重新安装时,可以继续访问先前存储的 Keychain 数据。然而,如果用户选择了“删除应用的数据”或使用特定第三方工具清理 Keychain 数据,相关的存储值可能会被删除。
4. 设备迁移
在某些情况下,通过 iCloud 备份或设备迁移将 Keychain 数据同步到新设备上。如果用户选择没有迁移 Keychain 数据(例如,设备迁移时选择了不备份 Keychain),那么新设备中的值会发生变化或丢失。
5. 越狱设备
越狱会增加 Keychain 数据被第三方工具访问、修改或删除的风险。尽管越狱本身不会直接改变 Keychain 中的值,但越狱后的应用和操作可能影响其数据完整性,可能导致 Keychain 数据被篡改或清除。
6. 应用自身操作
如果应用在某些条件下(如用户登出、换新账户、重装等)主动删除或更新 Keychain 中的数据,也会导致相关值发生变化。例如:
- (void)deleteIdentifierInKeychain {
NSString *key = @"com.yourcompany.yourapp.identifierForVendor";
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. 用户主动清除 Keychain
用户可以通过某些工具或设置,主动选择清除特定的 Keychain 数据,这样会导致存储值的删除或变化。
常见问题:
卸载和重新安装应用:
- 不恢复出厂设置:重装应用通常不会影响 Keychain 数据。
- 恢复出厂设置或重置所有设置:Keychain 数据会被删除。
设备切换:
- 如果用户在设备切换过程中未备份或恢复 Keychain 数据,新的 Keychain 数据将重新生成。
简而言之,尽管 Keychain 存储提供了一种相对持久的存储机制,在以下情况下存储值可能会发生变化或被清除:
- 恢复出厂设置或刷机。
- 设备迁移而未同步 Keychain 数据。
- 越狱引起的数据篡改或清除。
- 应用自身操作或用户主动清除 Keychain 数据。
iOS开发基础149-由UUIDString引发的思考的更多相关文章
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- iOS开发——总结篇&IOS开发基础知识
IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...
- IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- iOS开发基础-九宫格坐标(6)
继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...
- iOS开发基础-九宫格坐标(5)
继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...
- iOS开发基础-九宫格坐标(4)
对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...
- iOS开发基础-九宫格坐标(3)之Xib
延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍 Xib 和 storyboard 的比较: 1) X ...
- iOS开发基础-九宫格坐标(2)之模型
在iOS开发基础-九宫格(1)中,属性变量 apps 是从plist文件中加载数据的,在 viewDidLoad 方法中的第20行.26行中,直接通过字典的键名来获取相应的信息,使得 ViewCont ...
- iOS开发基础-图片切换(4)之懒加载
延续:iOS开发基础-图片切换(3),对(3)里面的代码用懒加载进行改善. 一.懒加载基本内容 懒加载(延迟加载):即在需要的时候才加载,修改属性的 getter 方法. 注意:懒加载时一定要先判断该 ...
- iOS开发基础-图片切换(3)之属性列表
延续:iOS开发基础-图片切换(2),对(2)里面的代码用属性列表plist进行改善. 新建 Property List 命名为 Data 获得一个后缀为 .plist 的文件. 按如图修改刚创建的文 ...
随机推荐
- windows nexus-3.20安装
1.Nexus官网:https://www.sonatype.com/download-oss-sonatype 2.环境变量NEXUS_HOME = D:\nexus-3.20.1-01-win64 ...
- JavaScript:JS对象_Array
<!DOCTYPE html><html> <head> <meta charset="utf-8"> ...
- scab2
package com.cmb.cox.utils;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;im ...
- 端口占用,无法通过netstat找到进程,占用的端口又不能修改,该怎么办?
最近遇到一个奇葩的问题,项目跑的好好的,没有安装其它特殊软件,突然服务器启动报错,日志如下,显然是服务器的8080端口占用了. Caused by: java.net.BindException: A ...
- 03-Python数据类型
None类型 Python3中没有NULL,取而代之的是空类型None.空列表.空字典等. None是一个特殊的Python对象,表示无. None的类型是NoneType. 如果只想声明变量,而不想 ...
- javaweb上传图片存到本地,并存储地址到数据库
前端使用layui的图片上传,将文件base64编码,然后在后端使用转码类来操作base64编码,并保存图片到本地,继而获取文件地址,将文件地址保存到数据库中 1.使用layui的图片上传 infos ...
- 记一次centos7.9崩溃恢复操作(limits.conf配置失误),救援模式
引起故障的原因:调整了操作系统的内核参数文件limits.conf,* soft nproc 131072 * hard nproc 131072 * soft nofile 65536 * ...
- Windows 10 LTSC中个人版OneDrive失效的问题
该问题是由于LTSC注册表无onedriver的id{A52BBA46-E9E1-435f-B3D9-28DAA648C0F6}定义导致,解决方案是新建一个reg_onedrive.reg文件,并编辑 ...
- Java 根据XPATH批量替换XML节点中的值
根据XPATH批量替换XML节点中的值 by: 授客 QQ:1033553122 测试环境 JDK 1.8.0_25 代码实操 message.xml文件 <Request service=&q ...
- ElementUI 基于vue+sortable.js实现表格行拖拽
基于vue+sortable.js实现表格行拖拽 By:授客 QQ:1033553122 实践环境 sortablejs@1.13.0 vue@2.6.11 element-ui@2.13.2 安装s ...