iOS中的永久存储也是相对的(以下所讲的永久存储也是如此),在用户不对设备进行恢复或还原操作时,部分数据是可以做到永久存储的(即应用被删除后重新安装数据不会丢失,在替代UUID方法中较为有效)。
几个概念:
1.UUID: (Universally Unique Identifier) 通用唯一标识符,是一个标识符标准用于软件架构,由开放软件基金会(OSF)作为分布式计算环境(DCE)的一部分而制作的标准。
UUID的目的是让分布式系统中的所有元素都能有唯一的辨识资讯,不需要透过中央控制端来做辨认资讯的制定。如此一来每个人都建立一个与其他人不同的标
识符,这样在存储到数据库中时,就不用担心名称相同的事情(功能类似数据库中的主键,但是数据库的主键只是在一张表中有效).
这个标准现在被广泛应用在微软的全球唯一标识上面(GUID)。
标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx (8-4-4-4-12)
2.GUID:(Globally Unique Identifier) 全球唯一标识符,是一个假随机数用于软件中
(1). 全球唯一性:世界上两台计算机生成的GUID都不相同,GUID主要用于拥有多个节点、多台计算机组成的计算机网络和系统中,分配具有唯一性的标志符。
在时间和空间上都能保证唯一性,保证在同一时间不同的地点生成的GUID值不同。
(2). 组成结构:通过特定算法生成的一个二进制长度为为128的字符串,在用GUID时是由算法自动生成,不需要任何机构来帮助。
GUID 的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。
例如:6F9619FF-8B86-D011-B42D-00C04FC964FF 即为有效的 GUID 值。------>一个16进制是4个二进制,所以共32位。
(3). 应用:世界上所有用户的每一个Office文档计算机都会自动生成一个GUID值,并作为这个Office的唯一标识符;而且这个GUID值与计算机的网卡是相关的,
但是这个GUID值对作者是不可见的。作者的信息可以通过GUID的值找到
3.UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成。
1、UIPasteboard 粘贴板
UIPasteboard最初被设计就是用于开发者的一组应用间的数据共享,当实际上iOS7之前的UIPasteboard只要应用知道其名字,即可访问其中的内容,而OpenUDID的实现方式也依赖于此,让开发者能使用一组UUID来标记一个设备。
iOS7之后,+[UIPasteboard pasteboardWithName:create:]和+[UIPasteboard pasteboardWithUniqueName]这两个方法产生的UIPasteboard仅供同组应用之间共享数据,也就是Info.plist中CFBundleIdentifier字段的前两段标识(例如com.yourcompany.xx的com.yourcompany)相同的应用才能相互共享数据。不同组应用之间相同名字的UIPasteboard是不同的,而不是以前的同一个。当然这并不影响永久存储,并且这些数据也没有必要和其它应用共享。
iOS上不只一个粘帖板:
有两个系统粘帖板:一个通用系统粘帖板用于复制/粘贴操作,一个查找粘帖板保存上一次搜寻用的字符串。
另外,应用程序还可以创建自己的粘帖板,甚至可以被其他应用程序使用。例如,零售机程序以及信用卡终端程序可以使用共享粘帖板来传递支付信息。
最常用的粘帖板操作包括获取/设置字符串,图像,URL和颜色。Apple提供了以下方便的方法:
使用通用粘帖板
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
查找粘贴板
获取
UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"testBoard" create:NO];
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:[pb dataForPasteboardType:@"myType"]];
caption.text = [dict objectForKey:@"content"];
存储
UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"testBoard" create:YES];
NSDictionary *dict = [NSDictionary dictionaryWithObject:textField.text forKey:@"content"];
NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dict];
[pb setData:dictData forPasteboardType:@"myType"];
2.KeyChain
iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。从ios 3.0开始,跨程序分享keychain变得可行。
如何需要在应用里使用使用keyChain,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,为减轻咱们程序员的开发,我们可以使用一些已经封装好了的工具类,下面我会简单介绍下我用过的两个工具类:KeychainItemWrapper和SFHFKeychainUtils(下载)。
创建
KeychainItemWrapper *keychain=[[KeychainItemWrapper alloc] initWithIdentifier:@"xxxxxx" accessGroup:nil];//xxxx 自定义
保存
[keyWrapper setObject:@"myChainValues" forKey:(id)kSecAttrService];
[keyWrapper setObject:[usernameTextField text] forKey:(id)kSecAttrAccount];// 上面两行用来标识一个Item
[keyWrapper setObject:[passwordTextField text] forKey:(id)kSecValueData];
读取
[usernameTextField setText:[keyWrapper objectForKey:(id)kSecAttrAccount]];
[passwordTextField setText:[keyWrapper objectForKey:(id)kSecValueData]];
另外需要引入Security.framework 和KeychainItemWrapper头文件
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"Account Number"
accessGroup:@"YOUR_APP_ID_HERE.com.yourcompany.AppIdentifier"];
//保存帐号
[wrapper setObject:@"<帐号>" forKey:(id)kSecAttrAccount];
//保存密码
[wrapper setObject:@"<帐号密码>" forKey:(id)kSecValueData];
//从keychain里取出帐号密码
NSString *password = [wrapper objectForKey:(id)kSecValueData];
//清空设置
[wrapper resetKeychainItem];