iOS持久化存储
2017-04-01 本文已影响77人
crazyfox
iOS有以下几种数据持久化方式
- NSUserDefault (无法保存自定义对象)
- plist表 (无法保存自定义对象)
- 归档 实现NSCoding协议 可以保存自定义对象
- SQLite3 框架FMDB http://www.jianshu.com/writer#/notebooks/10081699/notes/10839261
- CoreData 简单使用http://www.jianshu.com/p/1cd286a7d32f
- KeyChain
一.NSUserDafault
NSUserDefaults *userInfo = [NSUserDefaults standardUserDefaults];
NSLog(@"%@ %ld %@",[userInfo objectForKey:@"age"],[userInfo integerForKey:@"tizhong"],[userInfo objectForKey:@"family"]);
[userInfo setObject:@33 forKey:@"age"];
[userInfo setInteger:88 forKey:@"tizhong"];
[userInfo setObject:@[@"dad",@"mom",@"wife"] forKey:@"family"];
[userInfo synchronize];
输出
2017-03-31 23:25:48.501 CoreData[6987:560191] 33 88 (
dad,
mom,
wife
)
二.plist表
能存进plist表的数据类型
NSArray;
NSMutableArray;
NSDictionary;
NSMutableDictionary;
NSData;
NSMutableData;
NSString;
NSMutableString;
NSNumber;
NSDate;
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *fileName = [path stringByAppendingPathComponent:@"family.plist"];
NSArray *array = @[@"dad",@"mom",@"wife",@22,[@[@11,@22,@33]mutableCopy],[NSDate date]];
[array writeToFile:fileName atomically:YES];
NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
NSLog(@"%@", result);
输出
(
dad,
mom,
wife,
22,
(
11,
22,
33
),
"2017-03-31 15:39:26 +0000"
)
三.归档
@class Dog;
@interface Man : NSObject<NSCoding>
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,copy) Dog *dog;
@end
@implementation Man
@synthesize name;
@synthesize age;
@synthesize dog;
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:name forKey:@"name"];
[aCoder encodeInteger:age forKey:@"age"];
[aCoder encodeObject:dog forKey:@"dog"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
if(self = [super init])
{
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.dog = [aDecoder decodeObjectForKey:@"dog"];
}
return self;
}// NS_DESIGNATED_INITIALIZER
@end
参数dog类定义
@interface Dog : NSObject<NSCoding,NSCopying>
@property (nonatomic,copy) NSString *name;
@end
@implementation Dog
@synthesize name;
- (id)copyWithZone:(nullable NSZone *)zone
{
Dog *samo = [[self class] allocWithZone:nil];
samo.name = self.name;
return samo;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:name forKey:@"name"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
if(self = [super init])
{
self.name = [aDecoder decodeObjectForKey:@"name"];
}
return self;
}// NS_DESIGNATED_INITIALIZER
test代码
-(void)testKeyedArchiver
{
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *fileName = [path stringByAppendingPathComponent:@"some.data"];
Dog *dog = [[Dog alloc] init];
dog.name = @"heihei";
Man *m = [[Man alloc] init];
m.name = @"me";
m.age = 20;
m.dog = dog;
[NSKeyedArchiver archiveRootObject:m toFile:fileName];
Man *me = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
}
读取的归档
四.SQLite3
http://www.jianshu.com/writer#/notebooks/10081699/notes/10839261
五.CoreData
http://www.jianshu.com/p/1cd286a7d32f
六.KeyChain
manage
@interface QBZKeyChainManage : NSObject
//根据service创建用于操作keychain的dic
+ (NSMutableDictionary *)keyChainQueryDictionaryWithService:(NSString *)service;
//添加数据
+ (BOOL)addData:(id)data forService:(NSString *)service;
//查找数据
+ (id)queryDataWithService:(NSString *)service;
//更新数据
+ (BOOL)updateData:(id)data forService:(NSString *)service;
//删除数据
+ (BOOL)deletaDataWithService:(NSString *)service;
@implementation QBZKeyChainManage
//根据service创建用于操作keychain的dic
+ (NSMutableDictionary *)keyChainQueryDictionaryWithService:(NSString *)service
{
NSMutableDictionary *keyChainQueryDictionary = [@{} mutableCopy];
[keyChainQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[keyChainQueryDictionary setObject:service forKey:(id)kSecAttrService];
[keyChainQueryDictionary setObject:service forKey:(id)kSecAttrAccount];
return keyChainQueryDictionary;
}
//添加数据
+ (BOOL)addData:(id)data forService:(NSString *)service
{
NSMutableDictionary *keyChainQueryDictionary = [QBZKeyChainManage keyChainQueryDictionaryWithService:service];
SecItemDelete((CFDictionaryRef)keyChainQueryDictionary);
[keyChainQueryDictionary setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
OSStatus status = SecItemAdd((CFDictionaryRef)keyChainQueryDictionary, NULL);
if(status == noErr)
{
return YES;
}
return NO;
}
//查找数据
+ (id)queryDataWithService:(NSString *)service
{
id result;
NSMutableDictionary *keyChainQuery = [self keyChainQueryDictionaryWithService:service];
[keyChainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keyChainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keyChainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
result = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
}
@catch (NSException *exception) {
NSLog(@"不存在数据");
}
@finally {
}
}
if (keyData) {
CFRelease(keyData);
}
return result;
}
//更新数据
+ (BOOL)updateData:(id)data forService:(NSString *)service
{
NSMutableDictionary *searchDictionary = [self keyChainQueryDictionaryWithService:service];
if (!searchDictionary) {
return NO;
}
NSMutableDictionary *updateDictionary = [[NSMutableDictionary alloc] init];
[updateDictionary setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
OSStatus status = SecItemUpdate((CFDictionaryRef)searchDictionary,
(CFDictionaryRef)updateDictionary);
if (status == errSecSuccess) {
return YES;
}
return NO;
}
//删除数据
+ (BOOL)deletaDataWithService:(NSString *)service
{
NSMutableDictionary *keyChainDictionary = [self keyChainQueryDictionaryWithService:service];
OSStatus status = SecItemDelete((CFDictionaryRef)keyChainDictionary);
if (status == noErr) {
return YES;
}
return NO;
}
@end
test
-(IBAction)add:(id)sender
{
NSMutableDictionary *dic = [QBZKeyChainManage queryDataWithService:@"testData"];
if(dic)
{
self.label.text = [dic objectForKey:@"title"];
}else{
NSMutableDictionary *dic = [@{} mutableCopy];
[dic setObject:@"测试" forKey:@"title"];
[QBZKeyChainManage addData:dic forService:@"testData"];
}
}
两个app之间共享数据
Keychain设置参考http://www.jianshu.com/p/bf6b42470bba