Mantle Introduce

来源:互联网 发布:淘宝网短款连帽棉服 编辑:程序博客网 时间:2024/05/19 20:58

Mantle

Mantle是一个iOS模型框架,它为对象和JSON之间的相互转化提供了一种简便的方法。这在处理网络数据的时候非常有用。下面我们将看一下MTLModelMTLJSONAdapter以及为什么你将会考虑在下一个项目中使用Mantle。

MTLModel

MTLModel提供一个简便的方法在NSDictionary对象和自定义对象之间建立映射关系。首先我们来看一个例子。假设从远程服务器上获取了如下JSON数据,然后我们需要将它转化为自定义类型CATProfile的对象。

{    "id": 1,    "name":"objective Cat",    "birthday":"2013-09-12 13:29:36 +0100",    "website":"http://objc.at",    "location":{"lat":"48.2083","lon":"16.3731"},    "relationship_status":"single",    "awesome":true}

接下来创建一个MTLModel的子类用来表示上面的JSON对象。

//CATProfile.htypedef NS_ENUM(NSInteger, CATRelationshipStatus) {    CATRelationshipStatusSingle = 0,    CATRelationshipStatusRelationship,    CATRelationshipStatusComplicated};@interface CATProfile : MTLModel <MTLJSONSerializing>@property (strong, nonatomic) NSNumber *profileId;@property (strong, nonatomic) NSString *name;@property (strong, nonatomic) NSDate *birthday;@property (strong, nonatomic) NSURL *websiteURL;@property (nonatomic) CLLocationCoordinate2D locationCoordinate;@property (nonatomic) CATRelationshipStatus relationshipStatus;@property (nonatomic, getter=isAwesome) BOOL awesome;@end

CATProfile类继承自MTLModel并且实现了MTLJSONSerializing协议。该协议要求实现+JSONKeyPathsByPropertykey方法。

//CATProfile@implementation CATProfile+ (NSDictionary *)JSONKeyPathsByPropertyKey {    //头文件中定义的属性  < : > JSON字典中的key    return @{        @"profileId":   @"id",        @"websiteURL":  @"website",        @"locationCoordinate": @"location",        @"relationshipStatus": @"relationship_status",    };}@end

+JSONKeyPathsByPropertyKey返回一个NSDictionary用来建立JSON和模型对象属性之间的映射。如果模型属性没有出现在上面的字典里,Mantle自动将它与JSON中同名的值对应起来。

NSValueTransformer

Mantle可以自动处理NSStringNSNumber类型的数据,而对其它数据类型的值则需要我们提供一定的帮助才能正确转换。Mantle利用Foundation框架中的NSValueTransformer在JSON数据和实际模型属性之间建立映射。我们通过实现名为+<propertyName>JSONTransformer的类方法返回所需要的NSValueTransformer对象。

//将birthday映射到NSDate,反之亦然+ (NSValueTransformer *)birthdayJSONTransformer {    return [MTLValueTransformer reversibleTransfomerWithForwardBlock: ^(NSString *dateString) {        return [self.dateFormatter dateFromString: dateString];    } reverseBlock:^(NSDate *date) {        return [self.dateFormatter stringFromDate: date];    }];}+ (NSDateFormatter *)dateFormatter {    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];    dateFormatter.locale = [[NSLocale alloc] initWithLocaleIndentifier: @"en_US_POSIX"];    dateFormatter.dateFormat = @"yyyy-MM-dd 'T' HH:mm:ss.SSS 'Z'";    return dateFormatter;}

Mantle在运行时调用该方法来决定如何转换birthday属性。下面是其它类型属性的转换器方法。NSURL <->JSON string

+ (NSValueTransformer *)websiteURLJSONTransformer {    return [NSValueTransformer valueTransformerForName: MTLURLValueTransformerName];}

CLLocationCoordinate2D <-> JSON object

+ (NSValueTransformer *)locationCoordinateJSONTransformer {    return [MTLValueTranformer reversibleTransformerWithForwardBlock: ^(NSDictionary *coordicateDict){    CLLocationDegree latitude = [coordinateDict[@"lat"] doubleValue];    CLLocationDegree longitude = [coordinateDict[@"lon"] doubleValue];    return [NSValue valueWithMKCoordinate: CLLocationCoordinate2DMake(latitude, longitude)];    } reverseBlock:^(NSValue *coordinateValue){        CLLocationCoordinate2D coordinate = [coordinateValue MKCoordinateValue];        return @{@"lat":@(coordinate.latitude), @"lon":@(coordinate.longitude)};    }];}

enum <-> JSON string

+ (NSValueTransformer *)relationshipStatusJSONTransformer {    return [NSValueTransformer mtl_valueMappingTransformerWithDictionary: @{        @"single":@(CATRelationshipStatusSingle),        @"relationship":@(CATRelationshipStatusInRelationship),        @"complicated":@(CATRelationshipStatusComplicated)    }];}

BOOL <-> JSON boolean

+ (NSValueTransformer *)awesomeJSONTransformer {    return [NSValueTransformer valueTransformerForName: MTLBooleanValueTransformerName];}

从JSON创建模型对象

我们已经配置好了模型属性与JSON值的映射关系,可以开始将从API获取到的数据转换为模型对象了。第一步需要用NSJSONSerialization将JSON表示解析为NSDictionary供Mantle使用。然后通过MTLJSONAdapter将字典转换为模型对象。

//创建NSDictionaryNSData *JSONData = ...//接口的响应数据NSDictionary *JSONDict = [NSJSONSerialization JSONObjectWithData: JSONData options: 0 error: nil];//使用MTLJSONSerialization创建模型对象CATProfile *profile = [MTLJSONAdapter modelOfClass: CATProfile.class fromJSONDictionary: JSONDict error: NULL];

从模型对象创建JSON

MTLJSONAdapter同样可以用来从模型对象创建字典。

CATProfile *profile = ...NSDictionary *profileDict = [MTLJSONAdapter JSONDictionaryFromModel: profile];NSData *JSONData = [NSJSONSerialization dataWithJSONObject: profileDict options: 0 error: nil];

注意,如果模型中的属性如果没有对应的JSON值,应该在+JSONKeyPathsByPropertyKey的返回值中指定为NSNull.null,例如@{"name":NSNull.null},这样Mantle会自动忽略它。

映射数组和字典

许多模型相互之间都有关联,它们一般通过JSON数组和对象来表示。

{    "id": 1,    "name": "Objective Cat",    ...    "owner": {        "id":99,        "name":"Alexander Schuch"    },    "friends":[        {            "name":"Owly",            "type":"bird"        },        {            "name":"Hedgy",            "type":"mammal"        }    ]}

Mantle同样能很好的完成这些对象之间的映射。为了确保正确映射, 我们可以使用NSValueTransformer类别中的两个方法。

+ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass;+ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass;

当然,同样需要在模型类CATProfile中创建转换方法。

//CATProfile.h@property (strong, nonatomic) CATOwner *owner;@property (strong, nonatomic) NSArray *friends;//CATProfile.m+ (NSValueTransformer *)ownerJSONTransformer {    return [NSValueTransfomer mtl_JSONDictionaryTransfomerWithModelClass: CATOwner.class];}+ (NSValueTransformer *)friendsJSONTransfrmer {    return [NSValueTransformer mtl_JSONArrayTransformerWithMocelClass: CATFriend.class];}

来源:http://www.objc.at/mantle

转载:http://diveinedu.github.io/2014/12/12/Mantle-introduce.html

0 0
原创粉丝点击