[英]How to correctly migrate old data saved with NSKeyedArchiver into new format while migrating from Objective-C to Swift
该应用程序的旧版本具有符合NSCoding
的 class(我们称之为OldItem
),用 Objective C 编写。 这个 class 有大约 20 个不同类型的属性:
@property (nonatomic) NSInteger x;
// ...
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
_x = [coder decodeIntegerForKey:@"x"];
// all 20 fields are decoded in the similar way
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[self.x encodeWithCoder:coder];
// all 20 fields encoded in the similar way
}
它在另一个 class (我们称之为Controller
)中用作数组:
@property (nonatomic, strong, nonnull) NSMutableArray<OldItem *> *items;
Controller
还将项目缓存到磁盘,如下所示:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.items];
[data writeToFile:@"myfile.txt" options:NSDataWritingFileProtectionComplete error:nil];
现在我需要将OldItem
迁移到 Swift,而Controller
只更改它处理的项目类型:
@property (nonatomic, strong, nonnull) NSMutableArray<NewItem *> *items;
问题是:如何将旧版本的应用程序中保存在myfile.txt
中的旧数据迁移到新版本中?
NewItem
,但我愿意保留旧名称,如果它显着简化了迁移。OldItem
和NewItem
之间的任何差异。 将它们视为直接端口。NewItem
仍应符合NSCoding
标准,并且将NewItem
读/写到文件中不是问题。没有什么可以迁移的。 NSCoder 是 Cocoa 的东西,不是语言的东西; 无论您在 Objective C 或 Swift 中与它交谈,它的工作原理都是一样的。 只需将所有代码行逐行转换为 Swift 即可。 旧的存档数据继续正常工作,因为存档仍然是存档,编码器仍然是编码器。 Edit If the question is how to give your Swift class the old Objective C class's name so that the archive can be read into it, note that Objective C MyClass
and Swift MyClass
have different names because of Swift name mangling; 你不得不说
@objc(MyClass) class Whatever : NSObject {
看了一会,实际的解决办法是:
确保 NewItem class 中的public required init?(coder: NSCoder)
正确地取消归档您想要从 OldItem 保留的所有字段。 例如枚举或数字类型转换可能需要特殊处理,即使您没有更改字段本身。
在取消归档之前,使用NSKeyedUnarchiver.setClass
方法告诉NSKeyedUnarchiver
应该使用 NewItem 代替 OldItem。
例子:
let archivedData = try Data(contentsOf: filePath)
NSKeyedUnarchiver.setClass(NewItem.self, forClassName: "OldItem")
let items = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archivedData)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.