您可以拖动RMMapper文件夹到您的项目。此库必须启用ARC。
RMMapper可以通过CocoaPods安装。将以下行添加到您的Podfile中安装它。
pod 'RMMapper'
您可以通过以下方式获取类属性列表
+ (NSDictionary *)propertiesForClass:(Class)cls;
如果您有一个对象,并且希望从字典中填充其属性,这里有一个方法可以做到这一点
+ (id) populateObject:(id)obj fromDictionary:(NSDictionary*)dict;
有一个需要构建NSDictionary params用于AFNetworking的用例
+ (NSDictionary*) dictionaryForObject:(id)obj;
+ (NSDictionary*) dictionaryForObject:(id)obj include:(NSArray*)includeArray;
+ (NSMutableDictionary*) mutableDictionaryForObject:(id)obj;
+ (NSMutableDictionary*) mutableDictionaryForObject:(id)obj include:(NSArray*)includeArray;
您可以将对象转换为NSDictionary,这样NSLog也可以打印其值!
如果json是一个数组,我们也可以将字典的NSArray转换为预设类的对象数组。您可以在更多示例中查看。
+ (NSArray*) arrayOfClass:(Class)cls fromArrayOfDictionary:(NSArray*)array;
+ (NSMutableArray*) mutableArrayOfClass:(Class)cls fromArrayOfDictionary:(NSArray*)array;
RMMapper还支持您类中的关系。假设我们现在有如下JSON的房间
{
"id":879302,
"title":"My room",
"address":"Singapore",
"host":{"id":34045, "name":"David", "age":30, "email":"[email protected]"}
}
您可以定义以下RMRoom类
// RMRoom.h
#import "RMUser.h"
@interface RMRoom : NSObject
@property (nonatomic, retain) NSNumber* id;
@property (nonatomic, retain) NSString* title;
@property (nonatomic, retain) NSString* address;
@property (nonatomic, retain) RMUser* host;
@end
然后如果您想访问主机电子邮件,您可以使用room.host.email
如果您想将JSON键映射到类属性,您可以这样做。在您的模型类中,实现RMMapping
协议中的方法rm_dataKeysForClassProperties
#import "RMRoom.h"
@implementation RMRoom
- (NSDictionary *)rm_dataKeysForClassProperties
{
// country_code is json key, countryCode is class property
return @{
@"countryCode" : @"country_code",
@"currencyCode" : @"currency_code",
};
}
@end
如果您的属性是一个模型的其他模型的数组,您可以提供模型类以便自动解析
-(Class)rm_itemClassForArrayProperty:(NSString *)property {
if ([property isEqualToString:@"topping"]) {
return [RMTopping class];
}
return nil;
}
RMMapper在您想将自定义对象存档到NSUserDefaults或使对象可复制时非常有用。
如果您想使RMUser类可存档以便您可以将其保存到NSUserDefaults,只需在头文件中添加此代码即可
#import "NSObject+RMArchivable.h"
然后完成,您的类就准备好存档了!您可以使用分类NSUserDefaults+RMSaveCustomObject来帮助您更快地存档
#import "NSUserDefaults+RMSaveCustomObject.h"
// ...
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults rm_setCustomObject:user forKey:@"SAVED_DATA"];
从NSUserDefaults检索自定义对象
user = [defaults rm_customObjectForKey:@"SAVED_DATA"];
如果您想排除某些属性存档,您可以在类中的RMMapping
协议实现方法rm_excludedProperties
#import "RMUser.h"
@implementation RMUser
- (NSArray *)rm_excludedProperties
{
return @[@"display"];
}
@end
要使一个类可复制,只需将以下代码包含到您的类中
#import "NSObject+RMCopyable.h"
此库转换常见的数据结构,如NSDictionary或NSArray,到预设类的对象。它与Java中的Jackson或Gson库类似。
开发者常用的一个场景是从服务器获取数据并将数据填充到视图中。如果您使用AFNetworking,它已经将字符串转换为NSDictionary或NSArray,您可以使用它来构建视图。
让我们假设我们获取了如下用户json
{
"id": 50234
"name":"David",
"age":40,
"email":"[email protected]"
}
我们可以通过以下方式构建视图:
self.nameLabel.text = [dict objectForKey:@"name"];
self.ageLabel.text = [dict objectForKey:@"age"];
self.emailLabel.text = [dict objectForKey:@"email"];
这种方法可行,但不可扩展。来自服务器的响应可以包含20个或更多的不同键,手动输入[dict objectForKey:@"key"]既繁琐又容易出错。如果输入的键字符串错误,应用将会崩溃!编译器无法帮助我们检测错误,我们只能在运行时实际测试时发现这些崩溃。如果我们需要将数据传递给另一个控制器,我们将有更多的重复任务要做。更糟糕的是,如果服务器未来包含了更多的属性,那么我们必须编辑所有ViewController以添加额外的属性。
因此,我们必须找到一个更好的方法。这次我们定义一个普通模型类,当从服务器检索数据时,将NSDictionary/NSArray转换为普通模型对象。然后在视图中,我们可以简单地使用该类,Xcode会为我们自动补全字段。
让我们定义一个用于表示上面json的用户类
@interface RMUser : NSObject
@property (nonatomic, retain) NSNumber* id;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* email;
@property (nonatomic, retain) NSNumber* age;
@end
在视图中,它变成了
self.nameLabel.text = user.name;
self.ageLabel.text = [user.age stringValue];
self.emailLabel.text = user.email;
这样干净多了!Xcode会自动补全字段,所以我们不需要担心像以前那样输入错误的键。但是,我们仍然需要将数据转换为这个对象
RMUser* user = [[RMUser alloc] init];
user.name = [dict objectForKey:@"name"];
user.age = [dict objectForKey:@"age"];
user.email = [dict objectForKey:@"email"];
// Continue to parse the value...
编写上述代码很无聊,幸运的是,我们有更好的方法来做这件事。如果我们能检索对象的属性,我们可以使用setValue:forKey
方法从字典中为对象的属性设置值。
使用RMMapper,上面的代码变得超级简单
RMUser* user = [RMMapper objectWithClass:[RMUser class] fromDictionary:dict];
然后,字典中的所有值都将解析到user对象中!
获取类所有属性的代码取自http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c/13000074#13000074
感谢Farthen以及所有为该线程做出贡献的用户!
MIT许可证