JAGPropertyConverter 0.2.0

JAGPropertyConverter 0.2.0

测试测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年12月

未声明 维护。



  • James Gill

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。

  • 完整输出将任何未识别的 NSObject 子类"转换为"自身。因此,NSDictionary 将具有该对象的值。
  • 属性列表输出会删除任何未识别的 NSObject 子类,以便结果 NSDictionary 符合 PropertyList 规范。(但请参阅以下关于 NSURL 的部分)
  • JSON 输出会删除任何未识别的 NSObject 子类,以便结果 NSDictionary 符合 JSON 规范。(但请参阅以下关于 NSURL 和 NSDate 的部分)

模型

从模型到 NSDictionary 的转换相对简单,使用属性名称作为键,属性值作为值。从 NSDictionary 转换为模型需要识别由 NSDictionary 表示的 Model 类的重要第一步。JAGPropertyConverter 有一个名为 "identifyDict" 的 block 属性,它会检查任何 NSDictionary 值,并在返回一个 Class 时,转换器会尝试将 NSDictionary 转换为该类。如果 identifyDict 返回 nil,转换器将保持 NSDictionary 不变。

为了确定哪些 NSObject 子类被视为 "模型"(即应转换的类型),JAGPropertyConverter 依赖于其 classesToConvert 属性。对象的 Class 是 classesToConvert 中的 Class 的子类时将被转换。

默认情况下,弱/分配对象指针不被转换(但分配标量属性的属性)。这是因为弱引用通常表示保留循环(例如,在对象及其委托之间),这会导致对象图中的循环,从而在转换中形成一个无限循环。可以通过 JAGPropertyConverter 中的 "shouldConvertWeakProperties" 来控制此属性。

NSURL

NSURL 属性不是 JSON 或 ProperyLists 的有效属性,因此 JAGPropertyConverter 使用绝对路径的字符串序列化/反序列化它们。

NSDate

NSDate 属性对于 JSON 来说无意义,不同的用例可能需要不同的序列化方法。我们通过 convertToDate 和 convertFromDate block 属性允许这样做。当以 JSON 输出类型转换到/从 NSDate 属性时调用它们。

NSObject 属性

NSObject 本身拥有一些属性。JAGPropertyFinder 忽略这些属性。如果将来有需要,JAGPropertyFinder 可以通过设置来确定是忽略还是寻找这些属性。

NSSet

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 GillSpotNote 开发过程中创建。JAGProperty 的初始代码来自 Mike Ash 的 RTProperty 类,在他的出色的 运行时库 中。文档由 appledoc 生成,标签版本遵循 语义版本控制

许可

JAGPropertyConverter 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。