Skip to content

Commit 197bb47

Browse files
author
Blake Watters
committed
Merge branch 'release/0.22.0'
2 parents 24f116c + 29d5bc2 commit 197bb47

File tree

31 files changed

+306
-156
lines changed

31 files changed

+306
-156
lines changed

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.9.3-p429
1+
2.0.0-p247

Code/CoreData/RKManagedObjectMappingOperationDataSource.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ - (BOOL)mappingOperationShouldSkipPropertyMapping:(RKMappingOperation *)mappingO
455455

456456
RKPropertyMapping *propertyMappingForModificationKey = [[(RKEntityMapping *)mappingOperation.mapping propertyMappingsByDestinationKeyPath] objectForKey:modificationKey];
457457
id rawValue = [[mappingOperation sourceObject] valueForKeyPath:propertyMappingForModificationKey.sourceKeyPath];
458+
if (! rawValue) return NO;
458459
Class attributeClass = [entityMapping classForProperty:propertyMappingForModificationKey.destinationKeyPath];
459460

460461
id transformedValue = nil;

Code/Network/RKObjectManager.m

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@
6363
@param method The method for which to select matching response descriptors.
6464
@return An `NSArray` object whose elements are `RKResponseDescriptor` objects matching the given path and method.
6565
*/
66+
#ifdef _COREDATADEFINES_H
6667
static NSArray *RKFilteredArrayOfResponseDescriptorsMatchingPathAndMethod(NSArray *responseDescriptors, NSString *path, RKRequestMethod method)
6768
{
6869
NSIndexSet *indexSet = [responseDescriptors indexesOfObjectsPassingTest:^BOOL(RKResponseDescriptor *responseDescriptor, NSUInteger idx, BOOL *stop) {
6970
return [responseDescriptor matchesPath:path] && (method & responseDescriptor.method);
7071
}];
7172
return [responseDescriptors objectsAtIndexes:indexSet];
7273
}
74+
#endif
7375

7476
/**
7577
Returns the first `RKRequestDescriptor` object from the given array that matches the given object.
@@ -208,9 +210,9 @@ - (void)visitMapping:(RKMapping *)mapping
208210
@param responseDescriptors An array of `RKResponseDescriptor` objects.
209211
@return `YES` if the `mapping` property of any of the response descriptor objects in the given array is an instance of `RKEntityMapping`, else `NO`.
210212
*/
213+
#ifdef _COREDATADEFINES_H
211214
static BOOL RKDoesArrayOfResponseDescriptorsContainEntityMapping(NSArray *responseDescriptors)
212215
{
213-
#ifdef _COREDATADEFINES_H
214216
// Visit all mappings accessible from the object graphs of all response descriptors
215217
NSMutableSet *accessibleMappings = [NSMutableSet set];
216218
for (RKResponseDescriptor *responseDescriptor in responseDescriptors) {
@@ -234,10 +236,10 @@ static BOOL RKDoesArrayOfResponseDescriptorsContainEntityMapping(NSArray *respon
234236
}
235237
}
236238
}
237-
#endif
238239

239240
return NO;
240241
}
242+
#endif
241243

242244
BOOL RKDoesArrayOfResponseDescriptorsContainOnlyEntityMappings(NSArray *responseDescriptors);
243245
BOOL RKDoesArrayOfResponseDescriptorsContainOnlyEntityMappings(NSArray *responseDescriptors)
@@ -559,18 +561,35 @@ - (void)copyStateFromHTTPClientToHTTPRequestOperation:(AFHTTPRequestOperation *)
559561
- (RKObjectRequestOperation *)objectRequestOperationWithRequest:(NSURLRequest *)request
560562
success:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
561563
failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure
564+
{
565+
return [self objectRequestOperationWithRequest:request responseDescriptors:self.responseDescriptors success:success failure:failure];
566+
}
567+
568+
- (RKObjectRequestOperation *)objectRequestOperationWithRequest:(NSURLRequest *)request
569+
responseDescriptors:(NSArray *)responseDescriptors
570+
success:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
571+
failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure
562572
{
563573
Class HTTPRequestOperationClass = [self requestOperationClassForRequest:request fromRegisteredClasses:self.registeredHTTPRequestOperationClasses] ?: [RKHTTPRequestOperation class];
564574
RKHTTPRequestOperation *HTTPRequestOperation = [[HTTPRequestOperationClass alloc] initWithRequest:request];
565575
[self copyStateFromHTTPClientToHTTPRequestOperation:HTTPRequestOperation];
566576
Class objectRequestOperationClass = [self requestOperationClassForRequest:request fromRegisteredClasses:self.registeredObjectRequestOperationClasses] ?: [RKObjectRequestOperation class];
567-
RKObjectRequestOperation *operation = [[objectRequestOperationClass alloc] initWithHTTPRequestOperation:HTTPRequestOperation responseDescriptors:self.responseDescriptors];
577+
RKObjectRequestOperation *operation = [[objectRequestOperationClass alloc] initWithHTTPRequestOperation:HTTPRequestOperation responseDescriptors:responseDescriptors];
568578
[operation setCompletionBlockWithSuccess:success failure:failure];
569579
return operation;
570580
}
571581

572582
#ifdef _COREDATADEFINES_H
573583
- (RKManagedObjectRequestOperation *)managedObjectRequestOperationWithRequest:(NSURLRequest *)request
584+
managedObjectContext:(NSManagedObjectContext *)managedObjectContext
585+
success:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
586+
failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure
587+
{
588+
return [self managedObjectRequestOperationWithRequest:request responseDescriptors:self.responseDescriptors managedObjectContext:managedObjectContext success:success failure:failure];
589+
}
590+
591+
- (RKManagedObjectRequestOperation *)managedObjectRequestOperationWithRequest:(NSURLRequest *)request
592+
responseDescriptors:(NSArray *)responseDescriptors
574593
managedObjectContext:(NSManagedObjectContext *)managedObjectContext
575594
success:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
576595
failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure
@@ -579,7 +598,7 @@ - (RKManagedObjectRequestOperation *)managedObjectRequestOperationWithRequest:(N
579598
RKHTTPRequestOperation *HTTPRequestOperation = [[HTTPRequestOperationClass alloc] initWithRequest:request];
580599
[self copyStateFromHTTPClientToHTTPRequestOperation:HTTPRequestOperation];
581600
Class objectRequestOperationClass = [self requestOperationClassForRequest:request fromRegisteredClasses:self.registeredManagedObjectRequestOperationClasses] ?: [RKManagedObjectRequestOperation class];
582-
RKManagedObjectRequestOperation *operation = (RKManagedObjectRequestOperation *)[[objectRequestOperationClass alloc] initWithHTTPRequestOperation:HTTPRequestOperation responseDescriptors:self.responseDescriptors];
601+
RKManagedObjectRequestOperation *operation = (RKManagedObjectRequestOperation *)[[objectRequestOperationClass alloc] initWithHTTPRequestOperation:HTTPRequestOperation responseDescriptors:responseDescriptors];
583602
[operation setCompletionBlockWithSuccess:success failure:failure];
584603
operation.managedObjectContext = managedObjectContext ?: self.managedObjectStore.mainQueueManagedObjectContext;
585604
operation.managedObjectCache = self.managedObjectStore.managedObjectCache;
@@ -617,7 +636,7 @@ - (id)appropriateObjectRequestOperationWithObject:(id)object
617636
if (isManagedObjectRequestOperation && self.managedObjectStore) {
618637
// Construct a Core Data operation
619638
NSManagedObjectContext *managedObjectContext = [object respondsToSelector:@selector(managedObjectContext)] ? [object managedObjectContext] : self.managedObjectStore.mainQueueManagedObjectContext;
620-
operation = [self managedObjectRequestOperationWithRequest:request managedObjectContext:managedObjectContext success:nil failure:nil];
639+
operation = [self managedObjectRequestOperationWithRequest:request responseDescriptors:matchingDescriptors managedObjectContext:managedObjectContext success:nil failure:nil];
621640

622641
if ([object isKindOfClass:[NSManagedObject class]]) {
623642
static NSPredicate *temporaryObjectsPredicate = nil;
@@ -636,7 +655,7 @@ - (id)appropriateObjectRequestOperationWithObject:(id)object
636655
}
637656
} else {
638657
// Non-Core Data operation
639-
operation = [self objectRequestOperationWithRequest:request success:nil failure:nil];
658+
operation = [self objectRequestOperationWithRequest:request responseDescriptors:matchingDescriptors success:nil failure:nil];
640659
}
641660
#else
642661
// Non-Core Data operation

Code/Network/RKObjectParameterization.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ - (void)mappingOperation:(RKMappingOperation *)operation didSetValue:(id)value f
115115
} else if ([value isKindOfClass:[NSOrderedSet class]]) {
116116
// NSOrderedSets are not natively serializable, so let's just turn it into an NSArray
117117
transformedValue = [value array];
118+
} else if (value == nil) {
119+
// Serialize nil values as null
120+
transformedValue = [NSNull null];
118121
} else {
119122
Class propertyClass = RKPropertyInspectorGetClassForPropertyAtKeyPathOfObject(mapping.sourceKeyPath, operation.sourceObject);
120123
if ([propertyClass isSubclassOfClass:NSClassFromString(@"__NSCFBoolean")] || [propertyClass isSubclassOfClass:NSClassFromString(@"NSCFBoolean")]) {

Code/ObjectMapping/RKMappingOperation.m

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,17 @@ static id RKPrimitiveValueForNilValueOfClass(Class keyValueCodingClass)
8484
for (RKPropertyMapping *propertyMapping in propertyMappings) {
8585
NSString *sourceKeyPath = [propertyMapping.sourceKeyPath stringByReplacingOccurrencesOfString:searchString withString:replacementString];
8686
NSString *destinationKeyPath = [propertyMapping.destinationKeyPath stringByReplacingOccurrencesOfString:searchString withString:replacementString];
87+
RKPropertyMapping *nestedPropertyMapping = nil;
8788
if ([propertyMapping isKindOfClass:[RKAttributeMapping class]]) {
88-
[nestedMappings addObject:[RKAttributeMapping attributeMappingFromKeyPath:sourceKeyPath toKeyPath:destinationKeyPath]];
89+
nestedPropertyMapping = [RKAttributeMapping attributeMappingFromKeyPath:sourceKeyPath toKeyPath:destinationKeyPath];
8990
} else if ([propertyMapping isKindOfClass:[RKRelationshipMapping class]]) {
90-
[nestedMappings addObject:[RKRelationshipMapping relationshipMappingFromKeyPath:sourceKeyPath
91-
toKeyPath:destinationKeyPath
92-
withMapping:[(RKRelationshipMapping *)propertyMapping mapping]]];
91+
nestedPropertyMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:sourceKeyPath
92+
toKeyPath:destinationKeyPath
93+
withMapping:[(RKRelationshipMapping *)propertyMapping mapping]];
9394
}
95+
nestedPropertyMapping.propertyValueClass = propertyMapping.propertyValueClass;
96+
nestedPropertyMapping.valueTransformer = propertyMapping.valueTransformer;
97+
[nestedMappings addObject:nestedPropertyMapping];
9498
}
9599

96100
return nestedMappings;
@@ -421,6 +425,10 @@ - (NSArray *)relationshipMappings
421425

422426
- (BOOL)transformValue:(id)inputValue toValue:(__autoreleasing id *)outputValue withPropertyMapping:(RKPropertyMapping *)propertyMapping error:(NSError *__autoreleasing *)error
423427
{
428+
if (! inputValue) {
429+
*outputValue = nil;
430+
return YES;
431+
}
424432
Class transformedValueClass = propertyMapping.propertyValueClass ?: [self.objectMapping classForKeyPath:propertyMapping.destinationKeyPath];
425433
if (! transformedValueClass) {
426434
*outputValue = inputValue;
@@ -432,24 +440,24 @@ - (BOOL)transformValue:(id)inputValue toValue:(__autoreleasing id *)outputValue
432440
return success;
433441
}
434442

435-
- (void)applyAttributeMapping:(RKAttributeMapping *)attributeMapping withValue:(id)value
443+
- (BOOL)applyAttributeMapping:(RKAttributeMapping *)attributeMapping withValue:(id)value
436444
{
445+
id transformedValue = nil;
446+
NSError *error = nil;
447+
if (! [self transformValue:value toValue:&transformedValue withPropertyMapping:attributeMapping error:&error]) return NO;
448+
437449
if ([self.delegate respondsToSelector:@selector(mappingOperation:didFindValue:forKeyPath:mapping:)]) {
438450
[self.delegate mappingOperation:self didFindValue:value forKeyPath:attributeMapping.sourceKeyPath mapping:attributeMapping];
439451
}
440452
RKLogTrace(@"Mapping attribute value keyPath '%@' to '%@'", attributeMapping.sourceKeyPath, attributeMapping.destinationKeyPath);
441-
442-
id transformedValue = nil;
443-
NSError *error = nil;
444-
if (! [self transformValue:value toValue:&transformedValue withPropertyMapping:attributeMapping error:&error]) return;
445453

446454
// If we have a nil value for a primitive property, we need to coerce it into a KVC usable value or bail out
447455
if (transformedValue == nil && RKPropertyInspectorIsPropertyAtKeyPathOfObjectPrimitive(attributeMapping.destinationKeyPath, self.destinationObject)) {
448456
RKLogDebug(@"Detected `nil` value transformation for primitive property at keyPath '%@'", attributeMapping.destinationKeyPath);
449457
transformedValue = RKPrimitiveValueForNilValueOfClass([self.objectMapping classForKeyPath:attributeMapping.destinationKeyPath]);
450458
if (! transformedValue) {
451459
RKLogTrace(@"Skipped mapping of attribute value from keyPath '%@ to keyPath '%@' -- Unable to transform `nil` into primitive value representation", attributeMapping.sourceKeyPath, attributeMapping.destinationKeyPath);
452-
return;
460+
return NO;
453461
}
454462
}
455463

@@ -478,6 +486,7 @@ - (void)applyAttributeMapping:(RKAttributeMapping *)attributeMapping withValue:(
478486
}
479487
}
480488
[self.mappingInfo addPropertyMapping:attributeMapping];
489+
return YES;
481490
}
482491

483492
// Return YES if we mapped any attributes
@@ -499,9 +508,8 @@ - (BOOL)applyAttributeMappings:(NSArray *)attributeMappings
499508
}
500509

501510
id value = (attributeMapping.sourceKeyPath == nil) ? self.sourceObject : [self.sourceObject valueForKeyPath:attributeMapping.sourceKeyPath];
502-
if (value) {
511+
if ([self applyAttributeMapping:attributeMapping withValue:value]) {
503512
appliedMappings = YES;
504-
[self applyAttributeMapping:attributeMapping withValue:value];
505513
} else {
506514
if ([self.delegate respondsToSelector:@selector(mappingOperation:didNotFindValueForKeyPath:mapping:)]) {
507515
[self.delegate mappingOperation:self didNotFindValueForKeyPath:attributeMapping.sourceKeyPath mapping:attributeMapping];

Code/Support/RKOperationStateMachine.m

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,39 +58,39 @@ - (id)initWithOperation:(NSOperation *)operation dispatchQueue:(dispatch_queue_t
5858
// NOTE: State transitions are guarded by a lock via start/finish/cancel action methods
5959
TKState *readyState = [TKState stateWithName:RKOperationStateReady];
6060
__weak __typeof(&*self)weakSelf = self;
61-
[readyState setWillExitStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
61+
[readyState setWillExitStateBlock:^(TKState *state, TKTransition *transition) {
6262
[weakSelf.operation willChangeValueForKey:@"isReady"];
6363
}];
64-
[readyState setDidExitStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
64+
[readyState setDidExitStateBlock:^(TKState *state, TKTransition *transition) {
6565
[weakSelf.operation didChangeValueForKey:@"isReady"];
6666
}];
6767

6868
TKState *executingState = [TKState stateWithName:RKOperationStateExecuting];
69-
[executingState setWillEnterStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
69+
[executingState setWillEnterStateBlock:^(TKState *state, TKTransition *transition) {
7070
[weakSelf.operation willChangeValueForKey:@"isExecuting"];
7171
}];
7272
// NOTE: isExecuting KVO for `setDidEnterStateBlock:` configured below in `setExecutionBlock`
73-
[executingState setWillExitStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
73+
[executingState setWillExitStateBlock:^(TKState *state, TKTransition *transition) {
7474
[weakSelf.operation willChangeValueForKey:@"isExecuting"];
7575
}];
76-
[executingState setDidExitStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
76+
[executingState setDidExitStateBlock:^(TKState *state, TKTransition *transition) {
7777
[weakSelf.operation didChangeValueForKey:@"isExecuting"];
7878
}];
79-
[executingState setDidEnterStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
79+
[executingState setDidEnterStateBlock:^(TKState *state, TKTransition *transition) {
8080
[NSException raise:NSInternalInconsistencyException format:@"You must configure an execution block via `setExecutionBlock:`."];
8181
}];
8282

8383
TKState *finishedState = [TKState stateWithName:RKOperationStateFinished];
84-
[finishedState setWillEnterStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
84+
[finishedState setWillEnterStateBlock:^(TKState *state, TKTransition *transition) {
8585
[weakSelf.operation willChangeValueForKey:@"isFinished"];
8686
}];
87-
[finishedState setDidEnterStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
87+
[finishedState setDidEnterStateBlock:^(TKState *state, TKTransition *transition) {
8888
[weakSelf.operation didChangeValueForKey:@"isFinished"];
8989
}];
90-
[finishedState setWillExitStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
90+
[finishedState setWillExitStateBlock:^(TKState *state, TKTransition *transition) {
9191
[weakSelf.operation willChangeValueForKey:@"isFinished"];
9292
}];
93-
[finishedState setDidExitStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
93+
[finishedState setDidExitStateBlock:^(TKState *state, TKTransition *transition) {
9494
[weakSelf.operation didChangeValueForKey:@"isFinished"];
9595
}];
9696

@@ -134,7 +134,7 @@ - (void)start
134134
if (! self.dispatchQueue) [NSException raise:NSInternalInconsistencyException format:@"You must configure an `operationQueue`."];
135135
[self performBlockWithLock:^{
136136
NSError *error = nil;
137-
BOOL success = [self.stateMachine fireEvent:RKOperationEventStart error:&error];
137+
BOOL success = [self.stateMachine fireEvent:RKOperationEventStart userInfo:nil error:&error];
138138
if (! success) [NSException raise:RKOperationFailureException format:@"The operation unexpectedly failed to start due to an error: %@", error];
139139
}];
140140
}
@@ -145,7 +145,7 @@ - (void)finish
145145
dispatch_async(self.dispatchQueue, ^{
146146
[self performBlockWithLock:^{
147147
NSError *error = nil;
148-
BOOL success = [self.stateMachine fireEvent:RKOperationEventFinish error:&error];
148+
BOOL success = [self.stateMachine fireEvent:RKOperationEventFinish userInfo:nil error:&error];
149149
if (! success) [NSException raise:RKOperationFailureException format:@"The operation unexpectedly failed to finish due to an error: %@", error];
150150
}];
151151
});
@@ -169,7 +169,7 @@ - (void)setExecutionBlock:(void (^)(void))block
169169
{
170170
__weak __typeof(&*self)weakSelf = self;
171171
TKState *executingState = [self.stateMachine stateNamed:RKOperationStateExecuting];
172-
[executingState setDidEnterStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
172+
[executingState setDidEnterStateBlock:^(TKState *state, TKTransition *transition) {
173173
[weakSelf.operation didChangeValueForKey:@"isExecuting"];
174174
dispatch_async(weakSelf.dispatchQueue, ^{
175175
block();
@@ -181,7 +181,7 @@ - (void)setFinalizationBlock:(void (^)(void))block
181181
{
182182
__weak __typeof(&*self)weakSelf = self;
183183
TKState *finishedState = [self.stateMachine stateNamed:RKOperationStateFinished];
184-
[finishedState setWillEnterStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
184+
[finishedState setWillEnterStateBlock:^(TKState *state, TKTransition *transition) {
185185
[weakSelf performBlockWithLock:^{
186186
// Must emit KVO as we are replacing the block configured in `initWithOperation:queue:`
187187
[weakSelf.operation willChangeValueForKey:@"isFinished"];

0 commit comments

Comments
 (0)