首页 > 其他分享 >iOS开发基础149-由UUIDString引发的思考

iOS开发基础149-由UUIDString引发的思考

时间:2024-08-09 11:29:22浏览次数:17  
标签:status 存储 Keychain UUID UUIDString iOS 149 id identifierForVendor

问题1:[[UIDevice currentDevice] identifierForVendor].UUIDString什么情况下值会变化?

[[UIDevice currentDevice] identifierForVendor].UUIDString 是一个用于标识设备的唯一标识符(UUID),针对同一应用程序供应商(即同一开发者的应用程序集合),在设备上不变。然而,有一些情况会导致这个标识符发生变化:

情况导致 identifierForVendor 变化:

  1. 应用卸载和重装:当设备上来自同一供应商的所有应用程序都被卸载,再重新安装任意一个应用程序时,会生成新的 identifierForVendor。这意味着,如果用户完全清除你的应用并重新安装,它会获得一个新值。

  2. 设备恢复出厂设置:如果设备被恢复出厂设置,也会生成新的 identifierForVendor

除此之外,identifierForVendor 不会因为设备上的通常操作(如重启设备、软件更新等)而改变。

存储到 Keychain 的优势

Keychain 是一个安全存储敏感信息的系统级服务,适用于存储比如密码、证书和加密密钥等重要数据。把 identifierForVendor 存储到 Keychain 有一些优势:

  1. 持久性:即使用户删除了应用,Keychain 中存储的数据不会被删除。当用户重新安装应用时,可以从 Keychain 中恢复数据。
  2. 安全性:Keychain 提供了高安全性的存储方式,对敏感数据的保护比普通的文件存储要好得多。
  3. 跨应用共享:在适当的配置下,同一供应商的应用程序可以共享 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);
    }
}

步骤:

  1. 存储 UUID:使用 storeIdentifierForVendorInKeychain 方法将 identifierForVendor 存储到 Keychain 中。
  2. 检索 UUID:使用 retrieveUUIDFromKeychain 方法从 Keychain 中检索存储的 UUID。
  3. 删除 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 存储提供了一种相对持久的存储机制,在以下情况下存储值可能会发生变化或被清除:

  1. 恢复出厂设置或刷机。
  2. 设备迁移而未同步 Keychain 数据。
  3. 越狱引起的数据篡改或清除。
  4. 应用自身操作或用户主动清除 Keychain 数据。

标签:status,存储,Keychain,UUID,UUIDString,iOS,149,id,identifierForVendor
From: https://www.cnblogs.com/chglog/p/18350472

相关文章

  • vue中axios二次封装【简洁、附代码】+api解耦
    reference:https://www.bilibili.com/video/BV1my421h7hK/?share_source=copy_web&vd_source=334dbcc5ec1e90276a3fca594c89e11e下一篇:继axios二次封装后跨域问题解决——配置代理、环境变量文章目录一、axios请求接口1下载2引入3使用二、axios二次封装1.下......
  • 游戏性能超越i9-14900K!锐龙7 9700X/5 9600X首发评测:这才是真正优秀的游戏处理器
    一、前言:2家走上不同道路的微处理器公司Zen5性能提升不依赖频率和功耗很难理解像Intel这样有经验的公司,会在同一个问题上跌倒2次!2000年,在1GHz频率大战中铩羽而归的Intel,抢在AMD前面推出了当时频率最高的处理器——代号“铜矿”的奔腾III1.13GHz。但这颗处理器上市之后就大面......
  • iOS 语言基础与初探 Xcode 工具
    随着移动设备的广泛普及,iOS应用开发已成为一个充满机遇和挑战的领域。iOS是苹果公司为其移动设备(如iPhone和iPad)开发的操作系统,iOS应用主要使用Swift和Objective-C两种编程语言进行开发。掌握这两种语言的基础知识以及熟悉Xcode开发工具是开发iOS应用的核心技能......
  • 【iOS】SideTable
    目录SideTablesStripedMapSideTable1.spinlock_tslock2.RefcountMap3.weak_table_t总结objc4源码地址:SideTable&table=SideTables()[this];//获取对象的SideTablesize_t&refcntStorage=table.refcnts[this];SideTables查源码SideTables的结构如......
  • Xcode16升级后,如何直接安装iOS 18 Simulator
    热烈欢迎,请直接点击!!!进入博主AppStore主页,下载使用各个作品!!!注:博主将坚持每月上线一个新app!! 苹果官方下载链接:【操作系统OperatingSystems】:https://developer.apple.com/download/【应用Applications】:https://developer.apple.com/download/applications/【描述文件Pr......
  • iOS开发-属性的内存管理
    Objective-C中,类的实例变量(instancevariables)和属性(properties)是两种不同的概念,其中属性的内存管理就较为复杂。Objective-C提供了多种属性修饰符,用于管理对象的内存。这些修饰符用于控制对象的生命周期和内存管理行为。以下是一些常见的属性修饰符及其内存管理行为的详细介绍:......
  • iOS app启动优化
    app的启动阶段可分为main函数调用前和main函数调用后,分别都做了些什么呢1、pre-main阶段   1)加载应用的可执行文件(自身App的所有.o文件的集合)  2)加载动态链接器dyld(dynamicloader,是一个专门用来加载动态链接库的库)  3)dyld递归加载应用所有依赖的动态链接库dyli......
  • <转载>bios 关机过程
    [CSDNBIOS关机过程](https://blog.csdn.net/robinsongsog/article/details/50993333)热启动,冷启动,关机,这些词相信大家都很熟悉,今天就从BIOS的角度,说说这三种reset具体是怎么实现的。/**Resetthesystem.@paramResetTypewarmorcold@paramResetStatus......
  • uniapp 在微信H5、安卓、IOS预览PDF
    前言uniapp在微信内通过链接预览PDF,而现有uniapp插件都是通过在线网站解析例如:mumu-previewOffce但解析网站目前已经不能访问准备工作下载PDF.JShttps://github.com/mozilla/pdf.js/releases/download/v2.4.456/pdfjs-2.4.456-dist.zip放置在uniapp根目录static下并自......
  • Day18_2--Vue.js Ajax(使用 Axios)基础入门学习
    Vue.js中的Ajax请求(使用Axios)什么是Axios?Axios是一个基于Promise的HTTP客户端,可以用于浏览器和Node.js环境中。它是现代化的Ajax库,用来替代传统的XMLHttpRequest。为什么选择Axios?简单易用:Axios提供了简洁且强大的API,使得发送HTTP请求变得非常简单......