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: [email protected]
- Cocoapods - https://github.com/CocoaPods/CocoaPods
To install cocoapods you will need ruby.
gem install cocoapods
More information about cocoapods:
Add the dependency to your Podfile
:
platform :ios
...
pod 'EasyMapping', '~>0.4.9'
Run pod install
to install the dependencies.
- 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
If you are using CoreData objects use EKManagedObjectMapping
instead of EKObjectMapping
.
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 numbers!
- Dany L'Hébreux who added the NSSet support!
EasyMapping
requires iOS 5.x or greater.
Usage is provided under the MIT License. See LICENSE for the full details.
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