苹果禁用UUID了,咋办?
By now you have probably heard that Apple is deprecating support for attaining a UDID from an iOS device and furthermore that they will be rejecting any app submissions that use the UDID in any way. The now deprecated way of retrieving the UDID was:
NSString *udid = [[UIDevice currentDevice] identifier];
As we can no longer use this, but will often still have need of a unique identifier Apple has suggested using a CFUUID. To get a unique string identifier you now need to do this:
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
NSString *uuid = (NSString *)CFUUIDCreateString (kCFAllocatorDefault,uuidRef);
This gives you a unique identifier however if you called these methods again you would get a different unique identifier which may be fine if you only ever need to use this identifier once but for many situations this is probably not what you want. Apple suggests using NSUserDefaults to store the UUID after you have made it. You would do that like so:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:uuid forKey:@"UUID"];
Then if you need to retrieve the UUID at any point you would call:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *uuid = [userDefaults objectForKey:@"UUID"];
This is an ok solution. I say it is only ok because the problem with NSUserDefaults is that they do not persist if the user removes and reinstalls their application. This could wreak havoc on your app if for example the UUID is used to identify the device to a web service that served data to your app. Your users would find it frustrating to lose their data simply because they had reinstalled your app.
A better solution is to store the UUID in the users keychain.
If you are unfamiliar with the concept it is fairly simple. Each app has its own keychain that can be used to securely store passwords, certificates, keys etc. The keychain can even be shared among several different apps if needed though I will not cover that today.
To make working with the keychain simpler Apple wrote an Objective-C wrapper class called KeychainItemWrapper which you can find here.
To store our UUID in the keychain we first create a KeychainItemWrapper object with:
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:nil];
You can use whatever you want for the identifier. As I am only making this item available to this app I set the accessGroup to nil.
Now to save your UUID to the keychain use:
[keychainItem setObject:uuid forKey:(id)kUUID];
In this case I would have defined the constant kUUID with a # define such as:
#define kUUID @"UUID"
To retrieve your UUID you need to make a keychainItemWrapper object and then call objectForKey like this:
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:nil];
[keychainItem objectForKey:(id)kUUID];
This UUID that is stored in the keychain will now persist if the user removes the app and reinstalls and even if they save an encrypted backup and do a restore. It will not persist if they do a full reset of the device or restore from an unencrypted backup.
One word of warning, the keychain does not work in the iOS simulator.
Share and Enjoy:
苹果禁用UUID了,咋办?的更多相关文章
- iOS 杂笔-26(苹果禁用热更新)
iOS 杂笔-26(苹果禁用热更新) 苹果爸爸禁用热更新小伙伴们有什么想说的吗? 苹果爸爸禁用热更新小伙伴们有什么想说的吗? 苹果爸爸禁用热更新小伙伴们有什么想说的吗?
- Grub禁用UUID
这个属于一个个人喜好问题,我每次看到 df -h 的结果都很郁闷,根目录那一行设备是用uuid表示的,那一串字符真是够长的,看起来非常别扭,所以就自己修改了一下/etc/default/grub文件. ...
- 关于用户禁用Cookie的解决办法和Session的图片验证码应用
当用户通过客户端浏览页面初始化了Session之后(如:添加购物车,用户登陆等),服务器会将这些session数据保存在:Windows保存在C:\WINDOWS\Temp的目录下,Linux则是保存 ...
- 独家探寻阿里安全潘多拉实验室,完美越狱苹果iOS11.2.1
知道如何从攻击的视角去发现漏洞,才能建立更安全的体系,促进了整个生态的良性发展.以阿里安全潘多拉实验室为例,在对移动系统安全研究的过程中,把研究过程中发现的问题上报给厂商,促进系统安全性的提升. 小编 ...
- 蓝牙 BLE 三种 UUID 格式转换
蓝牙广播中对服务 UUID 格式定义都有三种 16 bit UUID.32 bit UUID.128 bit UUID. 但是熟悉安卓开发的小伙伴都知道接口都 UUID 格式,fromString 时 ...
- 低功耗蓝牙UUID三种格式转换
熟悉BLE技术同学应该对UUID不陌生,服务.特征值.描述都是有UUID格式定义. 蓝牙广播中对服务UUID格式定义都有三种16 bit UUID.32 bit UUID.128 bit UUID. ...
- Linux 硬盘UUID相同处理方法
OVF模板部署的linux虚拟机磁盘id是相同的,当同一个模板生成的虚拟机挂载虚拟机磁盘时就会遇到两个磁盘UUID相同的情况,导致系统启动后只能识别一个磁盘.这里介绍一下LVM分区的磁盘UUID相同的 ...
- 移动终端设备ID
转自:https://wetest.qq.com/lab/view/116.html 一.前言 对于移动端产品的常规统计分析和运营推广,渠道结算来说,能精准的识别区分并且跟踪一台终端设备(一个终端用户 ...
- 解决项目中.a文件的冲突
.a文件是静态文件,有多个.o文件组合而成的,在ios项目开发中,当引用第三方库的时候,时不时的会碰到诸如库冲突.库包含了某些禁用的API等问题,而这些库往往都被打包成了静态库文件(即 .a文件)来使 ...
随机推荐
- Bootstrap-Plugin:附加导航(Affix)插件
ylbtech-Bootstrap-Plugin:附加导航(Affix)插件 1.返回顶部 1. Bootstrap 附加导航(Affix)插件 附加导航(Affix)插件允许某个 <div&g ...
- Air test 基于屏幕比例实现滑动的方法
# -*- encoding=utf8 -*- __author__ = "chenshanju" __docs__ = "基于iOS类实现滑动" from a ...
- while循环-for循环
while true: 无限循环语句 break跳出循环,当count=1000的时候结束循环 count是结束当前循环'''count = 0while True: print("coun ...
- SQL常用条件操作符
1.SQL的六类内容: (1)数据定义语言(DDL): 创建.删除表结构的语句,包括Create.Drop (2)数据控制语言(DCL): 为定义数据访问及修改权限而实现的语句,包括Grant.Rev ...
- springboot 测试 有注入HttpSession的bean
question: nested exception is java.lang.IllegalStateException: No thread-bound request found: Are yo ...
- TLS协议扫盲(握手,非对称加密,证书,电子签名等)
想学习TLS协议最好的方法应该是去看RFC,但如果对安全传输协议没有一些基本认识的人很难一上来就读懂RFC里面的种种细节和设计原则,所以这里为了能够进一步去弄懂TLS协议,把一些基本的知识放在这里,算 ...
- delphi 路径函数
delphi path functionIncludeTrailingPathDelimiterIncludeTrailingPathDelimiter ensures that a path nam ...
- MyBait 符号大于 小于理解
EQ 就是 EQUAL等于 NQ 就是 NOT EQUAL不等于 GT 就是 GREATER THAN大于 LT 就是 LESS THAN小于 GE 就是 GREATER THAN OR EQUAL ...
- 14 并发编程-(协程)-greenlet模块&gevent模块
1.实现多个任务之间进行切换,yield.greenlet都没有实现检测I/O,greenlet在实现多任务切换下更简单 from greenlet import greenlet def eat(n ...
- 在coursera上有哪些值得推荐的课程
来自知乎 https://www.zhihu.com/question/22436320/answer/224996328