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

 

posted on 2018-10-13 01:38  梁飞宇  阅读(181)  评论(0)    收藏  举报