JAGPropertyConverter 是一个库,它允许轻松地将数据序列化和反序列化到/从 JSON 或 PropertyList 格式。
JAGPropertyConverter 允许您将 JSON 字典
{
"userID" : 1234,
"name" : "Jane Smith",
"likes" : ["swimming", "movies", "tennis"],
"invitedBy" : {
"userID" : 9876,
"name" : "Bob Willis"
},
"friends" : [
{ "userID" : 8873, "name" : "Jodi Fischer" },
{ "userID" : 9876, "name" : "Bob Willis" }
]
}
转换为/从 Objective-C "模型" 类,如
@interface User : NSObject
@property (assign) int userID;
@property (copy) NSString *name;
@property (strong) NSArray *likes;
@property (strong) User *invitedBy;
@property (strong) NSSet *friends;
@end
它通过使用 objc 运行时库来发现对象上定义了哪些属性,然后使用键值编码来设置/检索值来进行此操作。
它将以递归方式进行转换,因此具有数组属性模型字典的模型将被正确处理。
当从模型转换为 NSDictionary 时,转换器支持三个 "输出类型":完整、属性列表和 JSON。
从模型到 NSDictionary 的转换相对简单,使用属性名称作为键,属性值作为值。从 NSDictionary 转换为模型需要识别由 NSDictionary 表示的 Model 类的重要第一步。JAGPropertyConverter 有一个名为 "identifyDict" 的 block 属性,它会检查任何 NSDictionary 值,并在返回一个 Class 时,转换器会尝试将 NSDictionary 转换为该类。如果 identifyDict 返回 nil,转换器将保持 NSDictionary 不变。
为了确定哪些 NSObject 子类被视为 "模型"(即应转换的类型),JAGPropertyConverter 依赖于其 classesToConvert 属性。对象的 Class 是 classesToConvert 中的 Class 的子类时将被转换。
默认情况下,弱/分配对象指针不被转换(但分配标量属性的属性)。这是因为弱引用通常表示保留循环(例如,在对象及其委托之间),这会导致对象图中的循环,从而在转换中形成一个无限循环。可以通过 JAGPropertyConverter 中的 "shouldConvertWeakProperties" 来控制此属性。
NSURL 属性不是 JSON 或 ProperyLists 的有效属性,因此 JAGPropertyConverter 使用绝对路径的字符串序列化/反序列化它们。
NSDate 属性对于 JSON 来说无意义,不同的用例可能需要不同的序列化方法。我们通过 convertToDate 和 convertFromDate block 属性允许这样做。当以 JSON 输出类型转换到/从 NSDate 属性时调用它们。
NSObject 本身拥有一些属性。JAGPropertyFinder 忽略这些属性。如果将来有需要,JAGPropertyFinder 可以通过设置来确定是忽略还是寻找这些属性。
JAGPropertyConverter 根据需要将数组转换为集合,反之亦然。
//Serialization
MyModel *model = [MyModel populatedModel];
JAGPropertyConverter *converter = [[JAGPropertyConverter alloc] initWithOutputType:kJAGJSONOutput];
converter.classesToConvert = [NSSet setWithObject:[MyModel class]];
NSDictionary *jsonDictionary = [converter convertToDictionary:model];
//Deserialization
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithContentsOfFile:@"/path/to/model.json"];
JAGPropertyConverter *converter = [[JAGPropertyConverter alloc] init];
converter.identifyDict = ^(NSDictionary *dict) {
if ([dict valueForKey:@"userID"]) {
return [User class];
} else if ([dict valueForKey:@"primaryKey"]) {
return [MyModel class];
}
return nil;
}
MyModel *model = [converter composeModelFromObject:jsonDictionary];
该转换器可以处理 NSArray、NSSet 和 NSDictionary 输入。
由于 JAGPropertyConverter 使用键值编码来获取/设置值,因此它不尊重具有非标准名称的自定义获取器和设置器。JAGProperty 有这个能力,因此从理论上讲,我们可以支持它。目前有两件事阻止了我们这样做。首先,ARC 生成警告,因为你正在调用一个未知(对于它)的选择器来获取/设置属性,因此它不能确保内存管理被正确处理。其次,键值编码对标量处理得相当好,这需要更多的工作才能在直接使用属性获取器和设置器时完成。
虽然键值编码对结构体(和类似的)标量处理得相当好,但我们还没有启用 JAGPropertyConverter 将它们解析为 JSON 值格式。
JAGPropertyConverter 需要 iOS 4.0 或更高版本,并使用 ARC。从理论上讲,它也应该在 macOS 10.6 或更高版本上工作,但到目前为止,它仅用于 iOS 开发。
JAGPropertyConverter 由 James Gill 在 SpotNote 开发过程中创建。JAGProperty 的初始代码来自 Mike Ash 的 RTProperty 类,在他的出色的 运行时库 中。文档由 appledoc 生成,标签版本遵循 语义版本控制。
JAGPropertyConverter 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。