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.h
typedef 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字典中的keyreturn @{@"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将字典转换为模型对象。

//创建NSDictionary
NSData *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

Mantle Introduce相关推荐

  1. A饭福利,AMD Mantle API获众多游戏开发商青睐!

    摘要:Videocardz整理了一份2014年-2015年支持AMD Mantle游戏列表,并公布了游戏开发商及游戏引擎的名称.已发布且支持Mantle的游戏主要有<战地4>.<神偷 ...

  2. AMD Mantle再添新作,引发下代GPU架构猜想

    摘要:今年秋天即将发布的<希德梅尔文明:太空>将全面支持AMD Mantle API,如此强大的功能背后离不开强大的CPU.GPU支持.上周AMD爆出了下一代海盗岛R9 300系列,据网友 ...

  3. Mantle For iOS

    Mantle可以很方便的去书写一个模型层的代码. 使用它可以很方便的去反序列化JSON或者序列化为JSON(需要在MTLModel子类中实现<MTLJSONSerializing>协议) ...

  4. Introduce Null Object(引入Null对象)

    Introduce Null Object(引入Null对象) 你需要再三检查某对象是否为null. 将null值替换为null对象. if (customer == null) plan = Bil ...

  5. 功成身退:AMD Mantle不再优化了

    Mantle,AMD 2013年宣布的一个底层API技术,可让开发人员直接访问GCN GPU硬件底层,大大提高执行效率和性能,尤其是避免DirectX里存在的系统过载问题.大神卡马克就对Mantle赞 ...

  6. Java中introduce方法_Java基础—继承

    继承是面向对象的核心特征之一,是由已有类创建新类的机制.利用继承机制,可以先创建一个具有共性的一般类,然后根据该一般类创建具有特殊性的新类,新类继承一般类的属性和方法,并根据需要增加自己的新属性和方法 ...

  7. 6.5 Introduce Explaining Variable(引入解释性变量)

    概括         你有一个复杂的表达式.          将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名来解释表达式用途.       例子 if((platform.toUp ...

  8. Java中introduce方法,Introduce Foreign Method (引入外加函数)

    Summary: 你需要为提供服务的类增加一个函数.但你无法修改这个类.在客户类中建立一个函数,并以第一参数形式传入一个服务类实例. Motivation: 你正在使用一个类,它提供了所有需要的服务, ...

  9. 7.7 Introduce Foreign Method 引入外部方法

    在调用类中建立一个方法,并以第一参数形式传入一个服务类实例 更多精彩 更多技术博客,请移步 asing1elife's blog 后置条件 如果在调用类中引入了过多的方法,则需要考虑使用 7.8 In ...

最新文章

  1. php跳转方式带rere_PHP翻页跳转功能实现方法
  2. 平衡二叉排序树(完整案例详解及完整C代码实现)
  3. 向预训练进一步:掩码式非自回归模型训练
  4. lua excel to mysql_在Lua程序中使用MySQL的教程
  5. java if经典程序_java经典程序(11-20)
  6. Python测试开发django5.templates模板变量传参
  7. SSH-key连接原理
  8. 你不知道的 CSS 文档流技巧,让布局更简单
  9. Codeforces Round #FF(255) DIV2
  10. (翻译)Importing models-FBX Importer - Animations Tab
  11. python源码剖析笔记
  12. 三年级计算机测试题,小学三年级信息技术考试试题
  13. 营销哲学:小胜凭智,大胜靠德
  14. 360一键root su浅析
  15. BZOJ 1208 宠物收养所 Splay树
  16. obsidian如何修改主题
  17. Windows卸载与清除工具 “ Geek 与 CCleaner ”
  18. 计算机与音乐制作专业就业前景,计算机音乐制作专业就业形势不错
  19. 图卷积神经网络的数学原理——谱图理论和傅里叶变换初探
  20. FileUpload解析

热门文章

  1. 海马玩模拟器 修改host(让hosts生效)
  2. 解决Keystore was tampered with, or password was incorrect
  3. rtklib-单点定位(pntpos.c)代码关键问题解析-satposs部分
  4. 英语语法回顾1——简单句
  5. 身份验证错误,指定的句柄无效
  6. 【飞书系列】—— 飞书妙记:语音转文字,视频转文字
  7. ChunJunOceanBase联合方案首次发布:构建一体化数据集成方案
  8. java定时器每天执行一次_定时器-每天23:00执行一次
  9. 职业选手图解教你如何DIY装机
  10. mfc对话框ok没效果_利用PS制作逼真双重曝光效果案例演示,合成紫色城市建筑风格海报图片...