Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Eliminate unnecessary use of `targetObject` within `RKMapperOperation…

…` that prevents use of secondary object representations during mapping.
  • Loading branch information...
commit 49c5037139d0a5cfead61d0a35e7278d4933433c 1 parent 181c5c3
@percysnoodle percysnoodle authored blakewatters committed
View
21 Code/ObjectMapping/RKMapperOperation.m
@@ -20,6 +20,7 @@
#import "RKMapperOperation.h"
#import "RKMapperOperation_Private.h"
+#import "RKObjectMapping.h"
#import "RKObjectMappingOperationDataSource.h"
#import "RKMappingErrors.h"
#import "RKResponseDescriptor.h"
@@ -206,27 +207,13 @@ - (NSArray *)mapRepresentations:(id)representations atKeyPath:(NSString *)keyPat
RKLogWarning(@"Collection mapping forced but representations is of type '%@' rather than NSDictionary", NSStringFromClass([representations class]));
}
}
-
- NSMutableArray *mappedObjects = self.targetObject ? self.targetObject : [NSMutableArray arrayWithCapacity:[representations count]];
+
+ NSMutableArray *mappedObjects = [NSMutableArray arrayWithCapacity:[representations count]];
[objectsToMap enumerateObjectsUsingBlock:^(id mappableObject, NSUInteger index, BOOL *stop) {
id destinationObject = [self objectForRepresentation:mappableObject withMapping:mapping];
if (destinationObject) {
BOOL success = [self mapRepresentation:mappableObject toObject:destinationObject atKeyPath:keyPath usingMapping:mapping metadata:@{ @"mapping": @{ @"collectionIndex": @(index) } }];
- if (success) {
- @try {
- [mappedObjects addObject:destinationObject];
- }
- @catch (NSException *exception) {
- if ([[exception name] isEqualToString:NSInvalidArgumentException]) {
- NSString *errorMessage = [NSString stringWithFormat:
- @"Cannot map a collection of objects onto a non-mutable collection: %@", exception];
- [self addErrorWithCode:RKMappingErrorTypeMismatch message:errorMessage keyPath:keyPath userInfo:nil];
- *stop = YES;
- } else {
- [exception raise];
- }
- }
- }
+ if (success) [mappedObjects addObject:destinationObject];
}
*stop = [self isCancelled];
}];
View
2  RestKit.xcodeproj/project.pbxproj
@@ -973,6 +973,7 @@
8F2DFE1E847347368405F3B5 /* Pods-ios.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.xcconfig"; path = "Pods/Pods-ios.xcconfig"; sourceTree = SOURCE_ROOT; };
E457EFC3D502479D8B4FCF2A /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; };
ED192D1B86AB47D7927731B0 /* Pods-osx.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-osx.xcconfig"; path = "Pods/Pods-osx.xcconfig"; sourceTree = SOURCE_ROOT; };
+ F66056291744FF9000A87A45 /* and_cats.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = and_cats.json; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1414,6 +1415,7 @@
3EB0D83816ADCEFC00E9CEA2 /* empty_human.json */,
3E886DC0169E10A70069C56B /* has_many_with_to_one_relationship.json */,
25160FE31456F2330060A5C5 /* with_to_one_relationship.json */,
+ F66056291744FF9000A87A45 /* and_cats.json */,
);
path = humans;
sourceTree = "<group>";
View
17 Tests/Fixtures/JSON/humans/and_cats.json
@@ -0,0 +1,17 @@
+{
+ "cats" : [
+ {
+ "name": "Asia",
+ "id": 1234
+ },
+ {
+ "name": "Roy",
+ "id": 5678
+ }
+ ],
+ "human": {
+ "name": "Blake Watters",
+ "id": 1,
+ "catIDs" : [ 1234, 5678 ]
+ }
+}
View
33 Tests/Logic/ObjectMapping/RKObjectManagerTest.m
@@ -1428,4 +1428,37 @@ - (void)testShouldPropagateDeletionsUpToPersistentStore
expect(humans).to.haveCountOf(0);
}
+- (void)testPostingAnObjectAndGettingBackOtherObjectsCanConnectRelationsById
+{
+ RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
+ RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new];
+ managedObjectStore.managedObjectCache = managedObjectCache;
+
+ RKEntityMapping *humanEntityMapping = [RKEntityMapping mappingForEntityForName:@"Human" inManagedObjectStore:managedObjectStore];
+ humanEntityMapping.identificationAttributes = @[ @"railsID" ];
+ [humanEntityMapping addAttributeMappingsFromDictionary:@{ @"id": @"railsID", @"catIDs": @"catIDs" }];
+ [humanEntityMapping addConnectionForRelationship:@"cats" connectedBy:@{ @"catIDs" : @"railsID" }];
+
+ RKEntityMapping *catEntityMapping = [RKEntityMapping mappingForEntityForName:@"Cat" inManagedObjectStore:managedObjectStore];
+ catEntityMapping.identificationAttributes = @[ @"railsID" ];
+ [catEntityMapping addAttributeMappingsFromDictionary:@{ @"id": @"railsID" }];
+
+ NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
+ [childContext setParentContext:managedObjectStore.mainQueueManagedObjectContext];
+ RKHuman *human = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:childContext];
+
+ RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[RKTestFactory baseURL]];
+ objectManager.managedObjectStore = managedObjectStore;
+ [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:humanEntityMapping pathPattern:@"/humans/and_cats" keyPath:@"human" statusCodes:[NSIndexSet indexSetWithIndex:201]]];
+ [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:catEntityMapping pathPattern:@"/humans/and_cats" keyPath:@"cats" statusCodes:[NSIndexSet indexSetWithIndex:201]]];
+ __block RKMappingResult *mappingResult = nil;
+
+ [objectManager postObject:human path:@"/humans/and_cats" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *blockMappingResult) {
+ mappingResult = blockMappingResult;
+ } failure:nil];
+
+ expect(mappingResult).willNot.beNil();
+ expect(human.cats).to.haveCountOf(2);
+}
+
@end
View
5 Tests/Logic/ObjectMapping/RKObjectMappingNextGenTest.m
@@ -557,7 +557,7 @@ - (void)testShouldMapRegisteredSubKeyPathsOfAnUnmappableDictionaryAndReturnTheRe
#pragma mark Mapping Error States
-- (void)testShouldAddAnErrorWhenYouTryToMapAnArrayToATargetObject
+- (void)testThatMappingWithTargetObjectThatDoesNotMatchRepresentationWorks
{
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTestUser class]];
RKAttributeMapping *idMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"id" toKeyPath:@"userID"];
@@ -569,7 +569,8 @@ - (void)testShouldAddAnErrorWhenYouTryToMapAnArrayToATargetObject
RKMapperOperation *mapper = [[RKMapperOperation alloc] initWithRepresentation:userInfo mappingsDictionary:@{ [NSNull null]: mapping }];
mapper.targetObject = [RKTestUser user];
[mapper start];
- assertThatInteger(mapper.error.code, is(equalToInt(RKMappingErrorTypeMismatch)));
+ assertThat(mapper.error, is(nilValue()));
+ assertThat(mapper.mappingResult, hasCountOf(3));
}
- (void)testShouldAddAnErrorWhenAttemptingToMapADictionaryWithoutAnObjectMapping
View
5 Tests/Server/server.rb
@@ -46,6 +46,11 @@ def render_fixture(path, options = {})
{:human => {:name => "My Name", :id => 1, :website => "http://restkit.org/"}}.to_json
end
+ post '/humans/and_cats' do
+ content_type 'application/json'
+ render_fixture('/JSON/humans/and_cats.json', :status => 201)
+ end
+
post '/humans/fail' do
content_type 'application/json'
render_fixture('/JSON/errors.json', :status => 500)
Please sign in to comment.
Something went wrong with that request. Please try again.