RMMapper 1.1.5

RMMapper 1.1.5

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年12月

Thomas Dao维护。



RMMapper 1.1.5

  • 作者:
  • Thomas Dao

设置

您可以拖动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的使用

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许可证