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 的文件. 按如图修改刚创建的文 ...
随机推荐
- sqlUtil
package com.cmbchina.monitor.utils;import com.alibaba.druid.sql.ast.SQLStatement;import com.alibaba. ...
- Nuxt3 的生命周期和钩子函数(三)
title: Nuxt3 的生命周期和钩子函数(三) date: 2024/6/27 updated: 2024/6/27 author: cmdragon excerpt: 摘要:概述了Nuxt3的 ...
- 高通与At指令:基础概念
背景 在某个新基线上移植AT指令,发现有问题,因此收集了这个系列的 文章 作为 这方面的知识补充. 原文作者:laozhuxinlu,本文有删改. AT指令在产线中是一类比较重要的问题, 一天没来得及 ...
- Linux 环境编程:errno的基本用法
背景 error是一个包含在<errno.h>中的预定义的外部int变量,用于表示最近一个函数调用是否产生了错误.若为0,则无错误,其它值均表示一类错误. errno只在函数返回错误时才有 ...
- 『vulnhub系列』doubletrouble-1
『vulnhub系列』doubletrouble-1 下载地址 https://www.vulnhub.com/entry/doubletrouble-1,743/ 信息搜集 使用命令,获得存活靶机I ...
- 全志科技T3国产工业评估板规格书(四核ARM Cortex-A7,主频1.2GHz)
1 评估板简介 创龙科技TLT3-EVM是一款基于全志科技T3处理器设计的4核ARM Cortex-A7高性能低功耗国产评估板,每核主频高达1.2GHz,由核心板和评估底板组成. 评估板接口资源丰富, ...
- 虽然说自己是个废物,但年纪轻轻就有了120w
- 好消息!数据库管理神器 Navicat 推出免费精简版:Navicat Premium Lite
前言 好消息,前不久Navicat推出了免费精简版的数据库管理工具Navicat Premium Lite,可用于商业和非商业目的,我们再也不需要付费.找破解版或者找其他免费平替工具了,有需要的同学可 ...
- Linux Shell 常用命令 - 02篇
系列文章: Linux Shell 常用命令 - 01篇 8. shell 中各种括号的作用 参考 https://www.jb51.net/article/123081.htm https://ww ...
- 物联网浏览器(IoTBrowser)-基于计算机视觉开发的应用“智慧眼AIEye”
一.起因 最近毕业在家:),准备筹划社区运营和IoTBrowser升级的事务,遇到了一系列物业管理上的问题,本来出于好心提醒物业人员,结果反被误认为是打广告推销的,当时被激怒一下,后面一想也许这也是一 ...