任何对象的简单且灵活的映射。
假设你从一个类开始
@interface Person : NSObject
@property (copy, nonatomic) NSString *firstName;
@property (copy, nonatomic) NSString *lastName;
@property (strong, nonatomic) NSURL *avatarURL;
@end
现在假设你有一些 JSON
{
"first_name": "Harry",
"last_name": "Potter",
"avatars": ["http://...", "http://...", "http://..."]
}
让我们开始吧!
基因组只是 GNKGene
对象的数组。一个基因代表两个对象之间单个特征的映射。所以对于我们的 JSON
NSArray *jsonGenome = @[GNKMakeGene(@"first_name", @selector(firstName)),
GNKMakeGene(@"last_name", @selector(lastName)),
GNKMakeGene(@"avatars[0]", @selector(avatarURL), [URLTransformer new])];
然后我们就完成了!GNKGene
对象使用 GNKSourceTrait
、GNKReceivingTrait
和可选的 NSValueTransformer
进行初始化。通过允许你提供一个到三个参数并将它们尝试转换为正确的类型,GNKMakeGene
宏简化了这个过程。它非常智能,可以接受选择器和原始数字。不再需要输入 NSStringFromSelector(@selector(...))
只是为了添加一些编译时安全性。
有了我们的基因组后,我们可以使用它将 JSON 上的值传输到我们的模型
NSDictionary *json = ...;
Person *person = [Person new];
[GNKLab transferTraitsFromSource:json receiver:person genome:jsonGenome options:0];
person.firstName; // "Harry"
person.lastName; // "Potter"
person.avatarURL; // "http://..."
Tada!
现在假设我们从服务器获得了新的 JSON
{
"first_name": "Harry",
"last_name": "Porker",
"avatars": [...]
}
出于某种原因,我们只想有一个人的实例,并且只在需要时更新它。我们可以很容易地使用我们的基因组找出 JSON 是否与我们的实例具有不同的值
NSDictionary *newJSON = ...;
NSSet *differentGenes = [GNKLab findGenesWithDifferentTraitsFromSource:newJSON receiver:person genome:jsonGenome options:0];
differentGenes.count; // 1
differentGenes.anyObject; // "<GNKGene:...> first_name ==> firstName"
现在我们知道只需要更新 firstName
。实际上,我们可以直接将不同的基因转换为数组,并使用它作为新的基因组!
GeneticsKit 的驱动力是两个协议:GNKSourceTrait
和 GNKReceivngTrait
。这两个协议构成了 GNKGene
的指定初始化器的组成。为了掩盖一些实现繁琐的工作,GeneticsKit 提供了一个 GNKTrait
类簇以提供一些常用特性。
此外,一些 Foundation 类已被扩展,以符合 GNKSourceTraitConvertible
和 GNKReceivingTraitConvertible
协议。
基础类 | 协议 | 描述 |
---|---|---|
NSString |
GNKSourceTraitConvertible , GNKReceivingTraitConvertible |
将字符串转换为单个索引或键特征,或者转换为两者的序列。 |
NSNumber |
GNKSourceTraitConvertible , GNKReceivingTraitConvertible |
将数字转换为索引特征。 |
NSIndexPath |
GNKSourceTraitConvertible , GNKReceivingTraitConvertible |
将索引路径转化为一系列索引特性。 |
NSArray |
GNKSourceTraitConvertible , GNKReceivingTraitConvertible |
将数组转化为一系列特性。 |
NSOrderedSet |
GNKSourceTraitConvertible , GNKReceivingTraitConvertible |
将有序集转化为一系列特性。 |
NSIndexSet |
GNKSourceTraitConvertible |
将索引集转化为索引特性的聚合。 |
NSSet |
GNKSourceTraitConvertible |
将集合转化为特性的聚合。 |
NSNull |
GNKSourceTraitConvertible |
等同于标识特性。 |
你可能想知道,我为什么要用这个库?首先,它很简单。看看我们多快就能创建出我们的JSON基因组。其次,它非常灵活。因为我们已经将映射与模型类和源类型分离,如果我们突然发现我们还需要一个提供Person
实例的JSON源,我们不需要子类化Person
,而只需创建一个新基因组!例如,让我们考虑这个新的JSON源
[
"Harry", // The first name will always be index 0
"Potter", // The last name will always be index 1
[
{"url": "https://..."},
{...},
{...}
] // The array of avatars will always be index 2
]
这个JSON很糟糕,但如果我们需要它,我们可以处理它
NSArray *horribleGenome = @[GNKMakeGene(0, @selector(firstName)),
GNKMakeGene(1, @selector(lastName)),
GNKMakeGene(@"[2][0].url", @selector(avatarURL), [URLTransformer new])];
这对我们的jsonGenome
没有任何影响,因为为什么会这样呢?
GeneticsKit也非常灵活,因为它不需要对您的架构进行重大更改即可实现。如果您已在Core Data中创建了模型,您可以保留它们。如果您喜欢使用原始的NSMutableDictionary
模型,请继续!只要您创建了一个有意义的基因组,它就会工作。
如果您还没有被说服,或者您认为需要更重的工具,这里有一些您可以考虑的框架
GeneticsKit可以通过CocoaPods获得。要安装它,只需将以下行添加到您的Podfile中
pod "GeneticsKit"
Zach Radke, [email protected]
GeneticsKit在MIT许可下可用。有关更多信息,请参阅LICENSE文件。