Skip to content

Commit

Permalink
add CoreData serialization methods, that use NSManagedObjectContext.
Browse files Browse the repository at this point in the history
  • Loading branch information
DenTelezhkin committed Dec 7, 2014
1 parent 805657a commit f424080
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 0 deletions.
30 changes: 30 additions & 0 deletions EasyMapping/EKSerializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#import "EKObjectMapping.h"
#import "EKSerializer.h"
#import "EKManagedObjectMapping.h"

/**
`EKSerializer` is a class, that allows converting objects to their JSON representation, using `EKObjectMapping`. CoreData objects are supported too.
Expand Down Expand Up @@ -51,4 +52,33 @@
*/
+ (NSArray *)serializeCollection:(NSArray *)collection withMapping:(EKObjectMapping *)mapping;

/**
Convert CoreData managed object to JSON representation.
@param object object to convert.
@param mapping object mapping.
@param context NSManagedObjectContext objects are in. If you don't use context lookups in reverse blocks, you can simply pass nil.
@result parsed JSON in a form of NSDictionary.
*/
+ (NSDictionary *)serializeObject:(id)object
withMapping:(EKManagedObjectMapping *)mapping
fromContext:(NSManagedObjectContext *)context;

/**
Convert CoreData managed objects to JSON representation.
@param collection objects to convert.
@param mapping object mapping.
@param context NSManagedObjectContext objects are in. If you don't use context lookups in reverse blocks, you can simply pass nil.
@result parsed JSON in a form of NSArray.
*/
+ (NSArray *)serializeCollection:(NSArray *)collection
withMapping:(EKManagedObjectMapping*)mapping
fromContext:(NSManagedObjectContext *)context;
@end
63 changes: 63 additions & 0 deletions EasyMapping/EKSerializer.m
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,69 @@ + (NSArray *)serializeCollection:(NSArray *)collection withMapping:(EKObjectMapp
return [NSArray arrayWithArray:array];
}

+(NSDictionary *)serializeObject:(id)object withMapping:(EKManagedObjectMapping *)mapping fromContext:(NSManagedObjectContext *)context
{
NSMutableDictionary *representation = [NSMutableDictionary dictionary];

[mapping.propertyMappings enumerateKeysAndObjectsUsingBlock:^(id key, EKPropertyMapping *propertyMapping, BOOL *stop) {
[self setValueOnRepresentation:representation
fromManagedObject:object
withPropertyMapping:propertyMapping
inContext:context];
}];
[mapping.hasOneMappings enumerateKeysAndObjectsUsingBlock:^(id key, EKRelationshipMapping *mapping, BOOL *stop) {
id hasOneObject = [object valueForKey:mapping.property];

if (hasOneObject) {
NSDictionary *hasOneRepresentation = [self serializeObject:hasOneObject
withMapping:(EKManagedObjectMapping *)[mapping objectMapping]
fromContext:context];
[representation setObject:hasOneRepresentation forKey:mapping.keyPath];
}
}];
[mapping.hasManyMappings enumerateKeysAndObjectsUsingBlock:^(id key, EKRelationshipMapping *mapping, BOOL *stop) {

id hasManyObject = [object valueForKey:mapping.property];
if (hasManyObject) {
NSArray *hasManyRepresentation = [self serializeCollection:hasManyObject
withMapping:(EKManagedObjectMapping *)[mapping objectMapping]
fromContext:context];
[representation setObject:hasManyRepresentation forKey:mapping.keyPath];
}
}];

if (mapping.rootPath.length > 0) {
representation = [@{mapping.rootPath : representation} mutableCopy];
}
return representation;
}

+(NSArray *)serializeCollection:(NSArray *)collection withMapping:(EKManagedObjectMapping *)mapping fromContext:(NSManagedObjectContext *)context
{
NSMutableArray *array = [NSMutableArray array];

for (id object in collection) {
NSDictionary *objectRepresentation = [self serializeObject:object withMapping:mapping fromContext:context];
[array addObject:objectRepresentation];
}

return [NSArray arrayWithArray:array];
}

+(void)setValueOnRepresentation:(NSMutableDictionary *)representation fromManagedObject:(id)object
withPropertyMapping:(EKPropertyMapping *)propertyMapping inContext:(NSManagedObjectContext *)context
{
id returnedValue = [object valueForKey:propertyMapping.property];

if (returnedValue) {

if (propertyMapping.managedReverseBlock) {
returnedValue = propertyMapping.managedReverseBlock(returnedValue,context);
}
[self setValue:returnedValue forKeyPath:propertyMapping.keyPath inRepresentation:representation];
}
}

+ (void)setValueOnRepresentation:(NSMutableDictionary *)representation fromObject:(id)object withPropertyMapping:(EKPropertyMapping *)propertyMapping
{
id returnedValue = [object valueForKey:propertyMapping.property];
Expand Down
1 change: 1 addition & 0 deletions EasyMappingExample/Classes/Models/ManagedPerson.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) ManagedCar *car;
@property (nonatomic, retain) NSSet *phones;
@property (nonatomic, retain) NSString * gender;
@end

@interface ManagedPerson (CoreDataGeneratedAccessors)
Expand Down
1 change: 1 addition & 0 deletions EasyMappingExample/Classes/Models/ManagedPerson.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ @implementation ManagedPerson
@dynamic email;
@dynamic car;
@dynamic phones;
@dynamic gender;

static EKManagedObjectMapping * mapping = nil;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
+ (EKManagedObjectMapping *)personWithCarMapping;
+ (EKManagedObjectMapping *)personWithPhonesMapping;
+ (EKManagedObjectMapping *)personWithOnlyValueBlockMapping;
+ (EKManagedObjectMapping *)personWithReverseBlocksMapping;

// Fake mapping, is not backed up by CoreData model
+ (EKManagedObjectMapping *)complexPlaneMapping;
Expand Down
29 changes: 29 additions & 0 deletions EasyMappingExample/Classes/Providers/ManagedMappingProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,35 @@ + (EKManagedObjectMapping *)personMapping
}];
}

+(EKManagedObjectMapping *)personWithReverseBlocksMapping
{
EKManagedObjectMapping * personMapping = [self personWithCarMapping];
[personMapping mapKeyPath:@"gender" toProperty:@"gender"
withValueBlock:^id(NSString *key, id value, NSManagedObjectContext *context) {
if ([value isEqualToString:@"male"])
{
return @"husband";
}
else if ([value isEqualToString:@"female"])
{
return @"wife";
}
return nil;
} reverseBlock:^id(id value, NSManagedObjectContext *context) {
if ([value isEqualToString:@"husband"])
{
return @"male";
}
else if ([value isEqualToString:@"wife"])
{
return @"female";
}
return nil;
}];

return personMapping;
}

+ (EKManagedObjectMapping *)personWithCarMapping
{
return [EKManagedObjectMapping mappingForEntityName:NSStringFromClass([ManagedPerson class])
Expand Down
41 changes: 41 additions & 0 deletions EasyMappingExample/Tests/Specs/EKSerializerSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#import "Native.h"
#import "NativeChild.h"
#import <CoreLocation/CoreLocation.h>
#import <MagicalRecord/CoreData+MagicalRecord.h>
#import "ManagedMappingProvider.h"
#import "ManagedPerson.h"

SPEC_BEGIN(EKSerializerSpec)

Expand All @@ -33,6 +36,13 @@
[[EKSerializer should] respondToSelector:@selector(serializeCollection:withMapping:)];
});

specify(^{
[[EKSerializer should] respondToSelector:@selector(serializeObject:withMapping:fromContext:)];
});

specify(^{
[[EKSerializer should] respondToSelector:@selector(serializeCollection:withMapping:fromContext:)];
});
});

describe(@".serializeObject:withMapping:", ^{
Expand Down Expand Up @@ -557,6 +567,37 @@

});

describe(@"CoreData reverse mapping blocks", ^{

beforeEach(^{
[MagicalRecord setDefaultModelFromClass:[self class]];
[MagicalRecord setupCoreDataStackWithInMemoryStore];
});

context(@"object", ^{

__block ManagedPerson * person = nil;
__block NSDictionary * representation = nil;

beforeEach(^{
NSDictionary * info = [CMFixture buildUsingFixture:@"Person"];
NSManagedObjectContext * context = [NSManagedObjectContext MR_defaultContext];

person = [EKManagedObjectMapper objectFromExternalRepresentation:info
withMapping:[ManagedMappingProvider personWithReverseBlocksMapping]
inManagedObjectContext:context];
representation = [EKSerializer serializeObject:person
withMapping:[ManagedMappingProvider personWithReverseBlocksMapping]
fromContext:context];
});

specify(^{
[[person.gender should] equal:@"husband"];
[[[representation objectForKey:@"gender"] should] equal:@"male"];
});
});
});

});

SPEC_END
Expand Down

0 comments on commit f424080

Please sign in to comment.