【问题标题】:NSSecureCoding: Writing UIView to diskNSSecureCoding:将 UIView 写入磁盘
【发布时间】:2021-08-18 22:47:02
【问题描述】:

是否可以使用 NSSecureCoding 将 UIView 写入磁盘。下面的代码会导致错误。

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

错误:由于格式不正确,无法写入数据。

我们还尝试了以下方法:

NSMutableData *data = [NSMutableData data];
NSKeyedArchiver  *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
[archiver encodeObject:view forKey:@"view"];
[archiver finishEncoding];

错误:此解码器将仅解码采用 NSSecureCoding 的类。 'UIView' 类不采用它。

【问题讨论】:

  • 为什么要对 UIView 进行安全编码?据我了解,不安全编码的问题是,取消归档程序会构建一个对象图,该对象图可以转换为其他东西,让您以不需要的方式检查数据。我无法想象这种情况适用于 UIView。但也许您必须使用安全编码,因为它是必需的,例如 CoreData 中的 Transformable 属性。如果是这样,也许您可​​以不安全地将您的 UIView 归档到 NSData 对象,然后安全地编码 NSData 对象?我知道这是一个 hack,我不知道它是否有效,但我没有其他想法。
  • 嗨莱因哈德,感谢您的回复。确切地说,我们需要使用安全编码,因为它是必需的。我们尝试使用安全编码归档和取消归档包含 UIIView 对象的可变数组。不幸的是,将 UIView 归档到 NSData 不起作用,并返回数据格式不正确的错误。

标签: nskeyedarchiver nssecurecoding


【解决方案1】:

NSSecureCoding,除了 NSCoding 的要求,只需要类实现一个类函数 +(BOOL)supportsSecureCoding。 UIView 已经支持 NSCoding 并且它似乎可能是一个疏忽,它还没有符合 NSSecureCoding; Xcode 调试器会发出有关非 NSSecureCoding 序列化调用在遥远的将来消失的警告。

您可以使用类别将类函数添加到 UIView:

@interface UIView(SecureCoding)<NSSecureCoding>
@end

@implementation UIView(SecureCoding)
+ (BOOL)supportsSecureCoding {
    return TRUE;
}
@end

正如 cmets 中所指出的,这并不意味着您可以使用 NSKeyedUnarchiver 进行反序列化,因为 UIView 似乎不打算以这种方式进行序列化。我猜他们支持序列化的主要原因是 xibs/nibs/storyboards。下面是一个 UIView 序列化的示例,它确实有效,但使用私有 API,因此仅用于说明目的:

添加声明以访问未发布的 API:

/* Warning: Unpublished APIs!*/
@interface UINibEncoder : NSCoder
- initForWritingWithMutableData:(NSMutableData*)data;
- (void)finishEncoding;
@end

@interface UINibDecoder : NSCoder
- initForReadingWithData:(NSData *)data error:(NSError **)err;
@end

序列化/反序列化:

/* This does NOT work */
NSKeyedArchiver  *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:NO];
[archiver encodeObject:object forKey:@"view"];
[archiver finishEncoding];
data = [archiver encodedData];


NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&error];
/* error: 'UIBackgroundColor' was of unexpected class 'UIColor' */
data = [unarchiver decodeObjectForKey:@"view"];


/* This DOES work, but don't use it in an app you plan to publish */
NSMutableData *mData = [NSMutableData new];
UINibEncoder *encoder = [[UINibEncoder alloc] initForWritingWithMutableData:mData];

[encoder encodeObject:object forKey:@"view"];
[encoder finishEncoding];

UINibDecoder *decoder = [[UINibDecoder alloc] initForReadingWithData:mData error:&error];
NSObject *myView = [decoder decodeObjectForKey:@"view"];

【讨论】:

  • 感谢您的回复!我们已经尝试过了,但不幸的是,它不起作用。取消归档数据会返回数据格式不正确的错误。
  • 这是一个与所述问题不同的问题:如果您在示例中将安全编码设置为 FALSE/NO,您仍然会遇到相同的序列化错误。为答案添加更深入的解释以解释原因...
猜你喜欢
  • 1970-01-01
  • 2017-10-19
  • 2017-10-12
  • 2012-11-01
  • 2014-10-24
  • 2015-06-30
  • 2018-07-10
  • 1970-01-01
相关资源
最近更新 更多