JSACollection是一个将集合(例如字典和数组)转换为Objective-C对象的框架。这在将Plists和JSON数据转换为可用的Objective-C对象时非常有用。
有关序列化的信息,请阅读下面的部分,以下是对Swift包装的基本解释。
当前提供两个顶级函数,以Swift方式覆盖大多数使用功能。具体如下
func serializeObjects<C: SerializableContainer, T: NSObject>(container: C, type: T.Type = T.self, nonstandard: Bool = false) -> [T]
func serializeObjects<C: SerializableContainer, M: ClassSerializer>(container: C, mapper: M) -> [M.ObjectType]
第一个函数有几个自定义参数,但简单的使用方式仅需一个容器(字典或数组)
let objects: [Foo] = serializeObjects(["name": "bill"])
由于赋值给的是一个`Foo`类型的数组,编译器可以推断出类型。如果您的环境中无法实现这一点,您可以显式传递类型。
let objects = serializeObjects(["name": "bill"], type: Foo.self)
最后,您可以通过一个单独的可选参数确定是否支持非标准类型。
let objects: [Foo] = serializeObjects(["name": "bill"], nonstandard = true)
另一个函数简单接受一个容器和一个符合`ClassSerializer`协议的映射器。该映射器的行为几乎与`JSACSerializableClassFactory`相同,现在提供了一个Swift版本`ObjectMapper`,其行为几乎与其Objective-C版本相同,只是具有更简洁的语法和需要较少的类型转换。
JSACollection基于`JSACollectionSerializer`类构建。该类管理将`NSArrays`和`NSDictionaries`(我们将它们称为集合)转换为给定类的实例数组。标准实现可能看起来像这样
NSArray *arrayOfObjects = [[JSACCollectionSerializer sharedInstance] generateModelObjectsWithSerializableClass:[myClass class] fromContainer:myContainer];
使用此方法时,默认情况下,序列化器将生成对象的属性与JSON值之间的映射。但是,如果类定义了方法 +(NSDictionary *)JSONKeyMapping
,则序列化器将使用此方法返回的映射。此映射应使用存在在集合中的值作为键,对应属性名作为值进行设置(请注意,此值不应为nil)。
JSACollection提供了映射类JSACObjectMapper,以供API用户调整映射发生的方式。提供了一些几个方法来简化这个过程。
[mapper setSetterBlock:^id (NSDictionary *dict, id obj) {
//Perform custom object mapping
}];
这将替换映射器的映射机制,当找到表示对象的字典时,它会调用此代码块并提供该字典和一个新实例化的对象。如果您想要调用不同的初始化器或其他逻辑,则将返回的值将用于替换传入的对象。
[mapper addSetterForPropertyWithName:@"custom" withBlock:^(id value, id object) {
//Perform custom property mapping
}];
这使您可以在将字段映射到属性时执行某些操作,如果提供的名称已经是对象上的属性,则它不会设置它并只调用此代码块。但是,如果名称不是对象的属性,它仍然会映射并调用代码块,将值作为属性传递。
[mapper addSubObjectMapper:subMapper forPropertyName:@"bestHome"];
每当解析对象数组或需要映射非标准属性时,映射器会再次被调用,如果您想增强这种行为,可以通过此方法提供子映射器。
作为一种替代方法,而不是让序列化器决定创建,可以提供一个工厂,该工厂提供一个键的列表,并提供一个当给定字典时将创建对象的列表。这将类似如下所示
NSArray *arrayOfObjects = [[JSACCollectionSerializer sharedInstance] generateModelObjectsWithSerializableClassFactory:myFactory fromContainer:myContainer];
要创建一个工厂,对象应遵守JSACSerializableClassFactory
协议,并实现两个方法:-(NSArray *)listOfKeys
和 -(id)objectForDictionary:(NSDictionary *)dictionary
。
通常,序列化器仅尝试将JSON映射到如果属性类型是 NSString
、NSURL
、NSDictionary
、NSArray
或任何原始类型。但是,序列化器有属性 allowNonStandardTypes
,其类型为 BOOL
。默认情况下,此设置为 NO
,但如果将其更改为 YES
,则允许序列化器尝试将键映射到对象类型。
示例:设想您有一个这样一个结构的对象
@interface Foo : NSObject
@property (nonatomic, strong) NSString *nameString;
@property (nonatomic, strong) OtherFoo *otherFoo;
@end
想象您的集合是这样结构的
{
"nameString" : "Bob",
"otherFoo" : { "fooString" : "Foo", "fooType" : "strong" }
}
在Foo对象上,nameString
将设置为 "Bob"
,而 otherFoo
字段将设置为具有其 fooString
字段设置为 "Foo"
和其 fooType
字段设置为 "strong"
的对象。
使用提供的宏,您可以允许映射器执行更高级的操作,以便更正确和更复杂结构地进行映射。
JSAC_MODEL_CONFIGURE(Foo, {
USE_PARENT_PROPERTIES;
MAP_ARRAY_CLASS(arrayName, className);
ASSIGN_PARENT_REFERENCE(propertyName);
})
这些宏所做的如下所示
如果一个类有一个是数组的属性,它将直接将集合中的数组映射到该字段,这就是全部,这在不需要有一个OtherFoo
数组的NSString
时很有用。为了修复这个问题,在您的头文件中导入JSACMacros.h
并使用MAP_ARRAY_CLASS
宏。当实现后,它将看起来像以下这样:
@interface Foo : NSObject
@property (nonatomic, strong) NSArray *otherFooArray;
@end
JSAC_MODEL_CONFIGURE(Foo, {
MAP_ARRAY_CLASS(otherFooArray, OtherFoo);
})
就是这样,现在您的otherFooArray
里将充满了OtherFoo
对象。
如果一个类上有非标准的对象,并且您希望该对象有一个指向其父对象的引用,只需使用提供的宏。在您的头文件中导入JSACMacros.h
并使用ASSIGN_PARENT_REFERENCE
宏,当实现时,它将如下所示:
@interface Foo : NSObject
@property (nonatomic, strong) id parent;
@end
JSAC_MODEL_CONFIGURE(Foo, {
ASSIGN_PARENT_REFERENCE(parent);
})
这就是您需要做的全部,父属性现在将保持对Foo的父对象的引用。
属性名称映射到集合中包含的字段的方式如下(以下都是不区分大小写的):
JSACollection仅针对iOS 7.0+进行过测试,但应与iOS 6完全兼容,但在使用Swift时则至少需要iOS 8.0+。
需要ARC。对于不使用ARC的项目,可以在相关文件上设置编译器标志-fobjc-arc
。
请随意通过问题或提交Pull Request。
版权所有(c)2014 Nelson LeDuc
允许任何人免费获取本软件及其相关文档文件的副本("软件"),在不限制的情况下,包括但不限于使用、复制、修改、合并、发布、分发、转授权和/或销售软件副本的权利,并允许向提供软件的人提供进行此类操作的权利,前提是遵守以下条件:
上述版权声明和本许可声明应包含在软件的全部或主要部分中。
软件按"原样"提供,除非 Yapilma Muşulatı belirtilen taşıyıcılardan bir yazılım satın alındığını belirtmek için yıldız işaretleri eklemek gerekir,没有明示或暗示的保证,包括但不限于适销性、特定用途的适用性和非侵权性。在任何情况下,作者或版权持有人都不会因为合同行为、侵权或其他行为导致的索赔、损害或其他责任负责,无论这种索赔、损害或其他责任是否源于软件本身、使用或应对软件或其使用或其他处理。