iOS之文件管理(五)—NSKeyedArchive 文件归档
一,前言
使用情景:
在我们的实际开发过程中,为了更好的用户体验,可能需要在APP上存储用户的某些信息,比如淘宝APP会记录用户曾经填写过的收货地址。这种数据不方便用前面提到的NSUserDefaults来存储:
一是,因为地址数据是一个模型,NSUserDefaults只能用于NSString、NSArray、NSDictionary等常用的数据类型;
二是,用户还会经常对它进行增删改等操作,NSUserDefaults无法满足。此时,用NSKeyedArchive归档的形式来存储地址模型数据最符合要求。

二,使用方法
(1)创建地址模型CLVoiceApplyAddressModel
CLVoiceApplyAddressModel.h文件
#import <Foundation/Foundation.h> @interface CLVoiceApplyAddressModel : NSObject<NSCoding> //用于存储多个地址时,标记用户选中的状态 @property (nonatomic, copy) NSString *state; @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *phoneNum; @property (nonatomic ,copy) NSString *mainAddress; @property (nonatomic ,copy) NSString *detailAddress; +(instancetype)AddressModelWithDict:(NSDictionary *)dict; -(instancetype)initAddressModelWithDict:(NSDictionary *)dict; @end
CLVoiceApplyAddressModel.m文件
#import "CLVoiceApplyAddressModel.h"
@implementation CLVoiceApplyAddressModel
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_state forKey:@"state"];
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_phoneNum forKey:@"phoneNum"];
[aCoder encodeObject:_mainAddress forKey:@"mainAddress"];
[aCoder encodeObject:_detailAddress forKey:@"detailAddress"];
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
self.state= [aDecoder decodeObjectForKey:@"state"];
self.name = [aDecoder decodeObjectForKey:@"name"];
self.phoneNum = [aDecoder decodeObjectForKey:@"phoneNum"];
self.mainAddress = [aDecoder decodeObjectForKey:@"mainAddress"];
self.detailAddress = [aDecoder decodeObjectForKey:@"detailAddress"];
}else{
return nil;
}
return self;
}
+(instancetype)AddressModelWithDict:(NSDictionary *)dict{
return [[self alloc] initAddressModelWithDict:dict];
}
-(instancetype)initAddressModelWithDict:(NSDictionary *)dict{
if (self = [super init]) {
self.state =[dict objectForKey:@"state"];
self.name =[dict objectForKey:@"name"];
self.phoneNum =[dict objectForKey:@"phoneNum"];
self.mainAddress =[dict objectForKey:@"mainAddress"];
self.detailAddress =[dict objectForKey:@"detailAddress"];
}
return self;
}
@end
为了实现对归档地址的操作,我们专门创建了一个工具类:CLInvoiceApplyAddressModelTool。
#import <Foundation/Foundation.h> @class CLVoiceApplyAddressModel; @interface CLInvoiceApplyAddressModelTool : NSObject +(NSArray *)allAddressInfo; +(CLVoiceApplyAddressModel *)currentSelectedAddress; +(void)update; +(void)updateAddressInfoAfterDeleted; +(void)setSelectedAddressByNewInfoArray:(NSArray *)infoArray; +(void)addInfo:(CLVoiceApplyAddressModel *)info; +(void)removeInfoAtIndex:(NSUInteger)index; +(void)updateInfoAtIndex:(NSUInteger)index withInfo:(CLVoiceApplyAddressModel *)info; +(void)removeAllInfo; @end
#import "CLInvoiceApplyAddressModelTool.h"
#import "CLVoiceApplyAddressModel.h"
#define AddressInfosPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"addressInfo1.data"]
@implementation CLInvoiceApplyAddressModelTool
static NSMutableArray *_addressInfos;
+(NSArray *)allAddressInfo{
_addressInfos = [NSKeyedUnarchiver unarchiveObjectWithFile:AddressInfosPath];
if (!_addressInfos) _addressInfos = [NSMutableArray array];
return _addressInfos;
}
+(CLVoiceApplyAddressModel *)currentSelectedAddress{
CLVoiceApplyAddressModel *currentAddress;
BOOL hasSelectedAddress = NO;
if ([self allAddressInfo].count) {
for (CLVoiceApplyAddressModel *info in _addressInfos) {
if ([info.state isEqualToString:@"1"]) {
currentAddress = info;
hasSelectedAddress = YES;
break;
};
}
}else if([self allAddressInfo].count == 0 || hasSelectedAddress){
currentAddress = nil;
}
return currentAddress;
}
+(void)update{
[NSKeyedArchiver archiveRootObject:_addressInfos toFile:AddressInfosPath];
}
+(void)updateAddressInfoAfterDeleted{
if (_addressInfos.count) {
if (![self currentSelectedAddress]) {
CLVoiceApplyAddressModel *info = [CLInvoiceApplyAddressModelTool allAddressInfo][0];
info.state = @"1";
[CLInvoiceApplyAddressModelTool updateInfoAtIndex:0 withInfo:info];
}
}
}
+(void)setSelectedAddressByNewInfoArray:(NSArray *)infoArray{
[NSKeyedArchiver archiveRootObject:infoArray toFile:AddressInfosPath];
}
+(void)addInfo:(CLVoiceApplyAddressModel *)info{
if (!_addressInfos.count) {
_addressInfos = [NSMutableArray array];
}
for (CLVoiceApplyAddressModel *oldInfo in _addressInfos ) {
oldInfo.state = @"0";
}
[_addressInfos insertObject:info atIndex:0];
[self update];
}
+ (void)removeInfoAtIndex:(NSUInteger)index {
[_addressInfos removeObjectAtIndex:index];
[self update];
}
+ (void)removeAllInfo{
[_addressInfos removeAllObjects];
[self update];
}
+ (void)updateInfoAtIndex:(NSUInteger)index withInfo:(CLVoiceApplyAddressModel *)info {
[_addressInfos replaceObjectAtIndex:index withObject:info];
[self update];
}
@end
浙公网安备 33010602011771号