CoderMrWu

生活诚可期,爱情价更高!

IOS13下归档解档失败,原因是Apple新增安全策略SecureCoding

归档解档对IOS开发者来讲肯定很熟悉了,但是最近我使用归档解档的时候,我发现原来归档解档的api在IOS13下已经被废弃了,所有我尝试用新的api来做归档解档,却归档解档失败。容我思考一会。

正常的归档解档的代码是这样的。

在自定义类中中实现NSCoding协议


@interface KeyModel : NSObject<NSCoding>

@property(nonatomic,strong)NSString * className;

@property(nonatomic,strong)NSString * name;

@end

// 实现协议中的两个方法

- (void)encodeWithCoder:(NSCoder *)coder

{

    [coder encodeObject:self.className forKey:@"className"];

    [coder encodeObject:self.name forKey:@"name"];

    

}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {

    if (self == [super init]) {

        self.className = [coder decodeObjectForKey:@"className"];

        self.name = [coder decodeObjectForKey:@"name"];

    }

    return self;

}

// 实现归档和解档的代码

    KeyModel * model = [[KeyModel alloc] init];

    model.className = @"二年级三班";

    model.name = @"小明";

    // 设置归档目录,我这边是放在缓存目录下。

    NSString * path = [[FZFileManager defaultManager].tempPath stringByAppendingPathComponent:@"model.data"];

    NSError * error;

    // 归档: 我这边使用的是最新的归档的api,如果调用老版的api归档是没有问题的。

    NSData * data = [NSKeyedArchiver archivedDataWithRootObject:model requiringSecureCoding:YES error:&error];

    [data writeToFile:path atomically:YES];

    NSData * unData = [NSData dataWithContentsOfFile:path];

    //解档

    KeyModel * result = (KeyModel*)[NSKeyedUnarchiver unarchivedObjectOfClass:[KeyModel class] fromData:unData error:&error];

    NSLog(@"%@",result.className);

这个段代码是归档失败的,返回的data为空,通过错误信息可以看出,跟requiringSecureCoding 这个属性有关, 所以我尝试将其设置为NO,

NSData * data = [NSKeyedArchiver archivedDataWithRootObject:model requiringSecureCoding:NO error:&error];

归档成功了,但是解档还是失败了,根据错误信息看出,原因还是因为requiringSecureCoding属性。

所有我决定仔细看看api文档, 我发现了一个名为NSSecureCoding的协议,还有一个+(BOOL)supportsSecureCoding; 的方法。

所以最终的结果是这样的。

// 实现 NSSecureCoding 协议


@interface KeyModel : NSObject<NSSecureCoding>

@property(nonatomic,strong)NSString * className;

@property(nonatomic,strong)NSString * name;

@end

实现三个协议方法

- (void)encodeWithCoder:(NSCoder *)coder

{

    [coder encodeObject:self.className forKey:@"className"];

    [coder encodeObject:self.name forKey:@"name"];

    

}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {

    

    if (self == [super init]) {

        self.className = [coder decodeObjectForKey:@"className"];

        self.name = [coder decodeObjectForKey:@"name"];

    }

    return self;

}

// 这个需要返回YES

+(BOOL)supportsSecureCoding{

    return YES;

}

// 最终的实现效果

 KeyModel * model = [[KeyModel alloc] init];

model.className = @"二年级三班";

 model.name = @"小明";

 // 设置缓存l目录

NSString * path = [[FZFileManager defaultManager].tempPath stringByAppendingPathComponent:@"model.data"];

NSError * error;

 // 归档

NSData * data = [NSKeyedArchiver archivedDataWithRootObject:model requiringSecureCoding:YES error:&error];

 [data writeToFile:path atomically:YES];

 NSData * unData = [NSData dataWithContentsOfFile:path];

//解档

KeyModel * result = (KeyModel*)[NSKeyedUnarchiver unarchivedObjectOfClass:[KeyModel class] fromData:unData error:&error];

 NSLog(@"%@",result.className);

 

点赞