From 69f5e12750710add026a8b0288547629456d6bc8 Mon Sep 17 00:00:00 2001 From: Alexandar Drajev Date: Tue, 12 May 2015 17:13:09 +0300 Subject: [PATCH 1/3] Retry requests for updated objects 2 times --- AFIncrementalStore/AFIncrementalStore.m | 95 ++++++++++++++++--------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/AFIncrementalStore/AFIncrementalStore.m b/AFIncrementalStore/AFIncrementalStore.m index f6aabe3..d8bf4ea 100644 --- a/AFIncrementalStore/AFIncrementalStore.m +++ b/AFIncrementalStore/AFIncrementalStore.m @@ -602,8 +602,9 @@ - (id)executeSaveChangesRequest:(NSSaveChangesRequest *)saveChangesRequest if ([self.HTTPClient respondsToSelector:@selector(requestForUpdatedObject:)]) { for (NSManagedObject *updatedObject in [saveChangesRequest updatedObjects]) { + NSManagedObjectContext *backingContext = [self backingManagedObjectContext]; NSManagedObjectID *backingObjectID = [self objectIDForBackingObjectForEntity:[updatedObject entity] withResourceIdentifier:AFResourceIdentifierFromReferenceObject([self referenceObjectForObjectID:updatedObject.objectID])]; - + NSURLRequest *request = [self.HTTPClient requestForUpdatedObject:updatedObject]; if (!request) { [backingContext performBlockAndWait:^{ @@ -611,40 +612,14 @@ - (id)executeSaveChangesRequest:(NSSaveChangesRequest *)saveChangesRequest [self updateBackingObject:backingObject withAttributeAndRelationshipValuesFromManagedObject:updatedObject]; [backingContext save:nil]; }]; - continue; + return nil; } - - AFHTTPRequestOperation *operation = [self.HTTPClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { - BOOL isAuthenticated = YES; - if ([self.HTTPClient respondsToSelector:@selector(authenticateRequest:fromResponseObject:)]) { - isAuthenticated = [self.HTTPClient authenticateRequest:request fromResponseObject:responseObject]; - } - if (isAuthenticated) { - id representationOrArrayOfRepresentations = [self.HTTPClient representationOrArrayOfRepresentationsOfEntity:[updatedObject entity] fromResponseObject:responseObject]; - if ([representationOrArrayOfRepresentations isKindOfClass:[NSDictionary class]]) { - NSDictionary *representation = (NSDictionary *)representationOrArrayOfRepresentations; - [updatedObject setValuesForKeysWithDictionary:[self.HTTPClient attributesForRepresentation:representation ofEntity:updatedObject.entity fromResponse:operation.response]]; - - [backingContext performBlockAndWait:^{ - NSManagedObject *backingObject = [backingContext existingObjectWithID:backingObjectID error:nil]; - [self updateBackingObject:backingObject withAttributeAndRelationshipValuesFromManagedObject:updatedObject]; - [backingContext save:nil]; - }]; - [context refreshObject:updatedObject mergeChanges:YES]; - } - } - else { - NSLog(@"Update Error: authentication failed"); - [context refreshObject:updatedObject mergeChanges:NO]; - } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - NSLog(@"Update Error: %@", error); - [context refreshObject:updatedObject mergeChanges:NO]; - }]; - operation.completionGroup = group; - - [mutableOperations addObject:operation]; + AFHTTPRequestOperation *operation = [self operationForRequest:request updatedObject:updatedObject inManagedObjectContext:context]; + if (operation) { + operation.completionGroup = group; + [mutableOperations addObject:operation]; + } } } @@ -695,6 +670,60 @@ - (id)executeSaveChangesRequest:(NSSaveChangesRequest *)saveChangesRequest return [NSArray array]; } +- (AFHTTPRequestOperation *)operationForRequest:(NSURLRequest *)request updatedObject:(NSManagedObject *)updatedObject inManagedObjectContext:(NSManagedObjectContext *)context +{ + NSManagedObjectContext *backingContext = [self backingManagedObjectContext]; + NSManagedObjectID *backingObjectID = [self objectIDForBackingObjectForEntity:[updatedObject entity] withResourceIdentifier:AFResourceIdentifierFromReferenceObject([self referenceObjectForObjectID:updatedObject.objectID])]; + + AFHTTPRequestOperation *operation = [self.HTTPClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { + BOOL shouldRetry = [self.HTTPClient shouldRetryRequest:request forUpdatedObject:updatedObject]; + + BOOL isAuthenticated = YES; + if ([self.HTTPClient respondsToSelector:@selector(authenticateRequest:fromResponseObject:)]) { + isAuthenticated = [self.HTTPClient authenticateRequest:request fromResponseObject:responseObject]; + } + if (isAuthenticated) { + id representationOrArrayOfRepresentations = [self.HTTPClient representationOrArrayOfRepresentationsOfEntity:[updatedObject entity] fromResponseObject:responseObject]; + if ([representationOrArrayOfRepresentations isKindOfClass:[NSDictionary class]]) { + NSDictionary *representation = (NSDictionary *)representationOrArrayOfRepresentations; + [updatedObject setValuesForKeysWithDictionary:[self.HTTPClient attributesForRepresentation:representation ofEntity:updatedObject.entity fromResponse:operation.response]]; + + [backingContext performBlockAndWait:^{ + NSManagedObject *backingObject = [backingContext existingObjectWithID:backingObjectID error:nil]; + [self updateBackingObject:backingObject withAttributeAndRelationshipValuesFromManagedObject:updatedObject]; + [backingContext save:nil]; + }]; + + [context refreshObject:updatedObject mergeChanges:YES]; + } + } + else { + if (shouldRetry) { + [self.HTTPClient updateRetryMetadataForRequest:request forUpdateObject:updatedObject]; + AFHTTPRequestOperation *operation = [self operationForRequest:request updatedObject:updatedObject inManagedObjectContext:context]; + [operation start]; + } + else { + [context refreshObject:updatedObject mergeChanges:NO]; + } + NSLog(@"Update Error: authentication failed"); + } + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + BOOL shouldRetry = [self.HTTPClient shouldRetryRequest:request forUpdatedObject:updatedObject]; + NSLog(@"Update Error: %@", error); + if (shouldRetry) { + [self.HTTPClient updateRetryMetadataForRequest:request forUpdateObject:updatedObject]; + AFHTTPRequestOperation *operation = [self operationForRequest:request updatedObject:updatedObject inManagedObjectContext:context]; + [operation start]; + } + else { + [context refreshObject:updatedObject mergeChanges:NO]; + } + }]; + + return operation; +} + #pragma mark - NSIncrementalStore - (BOOL)loadMetadata:(NSError *__autoreleasing *)error { From 7d977f4382b4162c45009bd502f849a259703a40 Mon Sep 17 00:00:00 2001 From: Alexandar Drajev Date: Tue, 12 May 2015 19:37:16 +0300 Subject: [PATCH 2/3] Add missing methods in protocol --- AFIncrementalStore/AFIncrementalStore.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AFIncrementalStore/AFIncrementalStore.h b/AFIncrementalStore/AFIncrementalStore.h index 7ea486b..b8ba2db 100644 --- a/AFIncrementalStore/AFIncrementalStore.h +++ b/AFIncrementalStore/AFIncrementalStore.h @@ -288,6 +288,10 @@ - (BOOL)authenticateRequest:(NSURLRequest *)request fromResponseObject:(id)responseObject; +- (BOOL)shouldRetryRequest:(NSURLRequest *)request forUpdatedObject:(NSManagedObject *)updatedObject; + +- (void)updateRetryMetadataForRequest:(NSURLRequest *)request forUpdateObject:(NSManagedObject *)updatedObject; + @end ///---------------- From fde04247f209cc8d2e88eff2531003a3f1ed889c Mon Sep 17 00:00:00 2001 From: Alexandar Drajev Date: Thu, 14 May 2015 14:50:51 +0300 Subject: [PATCH 3/3] Retry only requests for SurveyQuestion object --- AFIncrementalStore/AFIncrementalStore.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AFIncrementalStore/AFIncrementalStore.m b/AFIncrementalStore/AFIncrementalStore.m index d8bf4ea..229bf7a 100644 --- a/AFIncrementalStore/AFIncrementalStore.m +++ b/AFIncrementalStore/AFIncrementalStore.m @@ -507,6 +507,7 @@ - (id)executeSaveChangesRequest:(NSSaveChangesRequest *)saveChangesRequest withContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error { + dispatch_group_t group = dispatch_group_create(); NSMutableArray *mutableOperations = [NSMutableArray array]; NSManagedObjectContext *backingContext = [self backingManagedObjectContext]; @@ -676,7 +677,7 @@ - (AFHTTPRequestOperation *)operationForRequest:(NSURLRequest *)request updatedO NSManagedObjectID *backingObjectID = [self objectIDForBackingObjectForEntity:[updatedObject entity] withResourceIdentifier:AFResourceIdentifierFromReferenceObject([self referenceObjectForObjectID:updatedObject.objectID])]; AFHTTPRequestOperation *operation = [self.HTTPClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { - BOOL shouldRetry = [self.HTTPClient shouldRetryRequest:request forUpdatedObject:updatedObject]; + BOOL shouldRetry = [updatedObject.entity.name isEqualToString:@"SurveyQuestion"] && [self.HTTPClient shouldRetryRequest:request forUpdatedObject:updatedObject]; BOOL isAuthenticated = YES; if ([self.HTTPClient respondsToSelector:@selector(authenticateRequest:fromResponseObject:)]) { @@ -709,7 +710,7 @@ - (AFHTTPRequestOperation *)operationForRequest:(NSURLRequest *)request updatedO NSLog(@"Update Error: authentication failed"); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - BOOL shouldRetry = [self.HTTPClient shouldRetryRequest:request forUpdatedObject:updatedObject]; + BOOL shouldRetry = [updatedObject.entity.name isEqualToString:@"SurveyQuestion"] && [self.HTTPClient shouldRetryRequest:request forUpdatedObject:updatedObject]; NSLog(@"Update Error: %@", error); if (shouldRetry) { [self.HTTPClient updateRetryMetadataForRequest:request forUpdateObject:updatedObject];