EasyMapping
An easy way to unmarshall a Dictionary of attributes (which came from JSON, XML or just a NSDictionary) into a Class and vice versa.
##Contact:
Developed by Lucas Medeiros E-mail: lucastoc@gmail.com
Development requirements
- Cocoapods - https://github.com/CocoaPods/CocoaPods
Install cocoapods
To install cocoapods you will need ruby.
gem install cocoapods
More information about cocoapods:
Cocoapods
Add the dependency to your Podfile
:
platform :ios
...
pod 'EasyMapping', '~>0.4.9'
Run pod install
to install the dependencies.
Usage
- Supose you have these classes:
typedef enum {
GenderMale,
GenderFemale
} Gender;
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, assign) Gender gender;
@property (nonatomic, strong) Car *car;
@property (nonatomic, strong) NSArray *phones;
@end
@interface Car : NSObject
@property (nonatomic, copy) NSString *model;
@property (nonatomic, copy) NSString *year;
@property (nonatomic, strong) NSDate *createdAt;
@end
@interface Phone : NSObject
@property (nonatomic, copy) NSString *DDI;
@property (nonatomic, copy) NSString *DDD;
@property (nonatomic, copy) NSString *number;
@end
@interface Native : NSObject
@property (nonatomic, readwrite) NSInteger integerProperty;
@property (nonatomic, readwrite) NSUInteger unsignedIntegerProperty;
@property (nonatomic, readwrite) CGFloat cgFloatProperty;
@property (nonatomic, readwrite) double doubleProperty;
@property (nonatomic, readwrite) BOOL boolProperty;
@end
- Map your classes in any place you want. An example:
#import "MappingProvider.h"
#import "Car.h"
#import "Phone.h"
#import "Person.h"
#import "Address.h"
@implementation MappingProvider
+ (EKObjectMapping *)carMapping
{
return [EKObjectMapping mappingForClass:[Car class] withBlock:^(EKObjectMapping *mapping) {
[mapping mapFieldsFromArray:@[@"model", @"year"]];
[mapping mapKey:@"created_at" toField:@"createdAt" withDateFormat:@"yyyy-MM-dd"];
}];
}
+ (EKObjectMapping *)phoneMapping
{
return [EKObjectMapping mappingForClass:[Phone class] withBlock:^(EKObjectMapping *mapping) {
[mapping mapFieldsFromArray:@[@"number"]];
[mapping mapFieldsFromDictionary:@{
@"ddi" : @"DDI",
@"ddd" : @"DDD"
}];
}];
}
+ (EKObjectMapping *)personMapping
{
return [EKObjectMapping mappingForClass:[Person class] withBlock:^(EKObjectMapping *mapping) {
NSDictionary *genders = @{ @"male": @(GenderMale), @"female": @(GenderFemale) };
[mapping mapFieldsFromArray:@[@"name", @"email"]];
[mapping mapKey:@"gender" toField:@"gender" withValueBlock:^(NSString *key, id value) {
return genders[value];
} withReverseBlock:^id(id value) {
return [genders allKeysForObject:value].lastObject;
}];
[mapping hasOneMapping:[self carMapping] forKey:@"car"];
[mapping hasManyMapping:[self phoneMapping] forKey:@"phones"];
}];
}
+ (EKObjectMapping *)nativeMapping
{
return [EKObjectMapping mappingForClass:[Native class] withBlock:^(EKObjectMapping *mapping) {
[mapping mapFieldsFromArray:@[
@"integerProperty", @"unsignedIntegerProperty",
@"cgFloatProperty", @"doubleProperty",
@"boolProperty"
]];
}];
}
- Converting a NSDictionary or NSArray to a object class or collection now becomes easy:
Person *person = [EKMapper objectFromExternalRepresentation:personRepresentation
withMapping:[MappingProvider personMapping]];
NSArray *carsArray = [EKMapper arrayOfObjectsFromExternalRepresentation:carsRepresentation
withMapping:[MappingProvider carMapping]];
- Converting an object/collection to NSDictionary/NSArray:
NSDictionary *representation = [EKSerializer serializeObject:car withMapping:[MappingProvider carMapping]];
NSArray *collectionRepresentation = [EKSerializer serializeCollection:cars withMapping:[MappingProvider carMapping]];
- Filling an existent object:
Supose you have something like this:
Person *person = [Person alloc] init]
To fill an already instantiated object you can do this:
[EKMapper fillObject:person fromExternalRepresentation:personRepresentation withMapping:[Mappings personMapping]];
- See the specs code
CoreData
If you are using CoreData objects use EKManagedObjectMapping
instead of EKObjectMapping
.
Thanks
Thanks to:
- basitali who added the fillObject functionality on EKMapper!
- Alejandro who added CoreData support!
- DenHeadless who added the ability to use different naming in hasOne and hasMany mappings!
- ArtFeel who added the ability to serialization/deserialization of primitive types!
- Dany L'HĂ©breux who added the NSSet support!
Requirements
EasyMapping
requires iOS 5.x or greater.
Usage is provided under the MIT License. See LICENSE for the full details.
The idea
The idea came from:
- RestiKit's mapping, its problem is that it doesn't transform custom values (such as a string value to an enum)
- Mantle's mapping, but you don't need to inherit from any class