苹果禁用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文件)来使 ...
随机推荐
- Firefox渗透插件—Web渗透必备工具
1:Firebug Firefox的 五星级强力推荐插件之一,不许要多解释 2:User Agent Switcher 改变客户端的User Agent的一款插件 3:Hackbar 攻城师们的必备工 ...
- 手动更新花生壳域名的动态IP
http://帐号:密码@ddns.oray.com/ph/update?hostname=hahaha.vicp.cc&myip=182.xx.200.xx 花生壳的文档地址 例子 1.使用 ...
- 微信小程序设置底部导航栏目方法
微信小程序底部想要有一个漂亮的导航栏目,不知道怎么制作,于是百度找到了本篇文章,分享给大家. 好了 小程序的头部标题 设置好了,我们来说说底部导航栏是如何实现的. 我们先来看个效果图 这里,我们添加了 ...
- WinForm应用程序中实现自动更新功能
WinForm应用程序中实现自动更新功能 编写人:左丘文 2015-4-20 近来在给一客户实施ECM系统,但他们使用功能并不是我们ECM制造版提供的标准功能,他们要求对系统作一些定制功能,为了避免因 ...
- LCD RGB 控制技术讲解 — 时钟篇(上)
时序图 下面是LCD RGB 控制的典型时序图 天啊,一下就上这玩意,怎么看??? 其实要解释上面的时序图,我们还需要了解一些LCD的显示过程.所以现在只是有个印象,稍后我们详细讲解. LCD显示流 ...
- java Long
1. Long.valueOf(b) 返回的是对象 public static Long valueOf(String s) throws NumberFormatException { )); } ...
- WinForm各浏览器内核控件
WebKit.NET webkit-sharp CefSharp awesomium OpenWebKitSharp geckofx MozNet Web Component
- bin sh git@github.com no such file or directory
window下使用git: 输入命令:git clone git @github.com:Alan0521/dotvim.git 出现/bin/sh:git@github.com no such fi ...
- php 数字格式化
php 数字格式化 1.位数不足前面补0 <?php for($i=1; $i<=17 ;$i++){ $var = sprintf("0%3d",$i); echo ...
- ScheduledExecutorService 定时器用法
1,如果只是想简单的写个定时任务,比如10分钟跑一次,那么ScheduledExecutorService是比较方便的,下面举个简单的例子 import java.util.concurrent.Ex ...