mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-05-06 17:32:52 +08:00
Introduce a new heuristic based approach for determining if a response can skip the mapping process. Also introduces a new Network + CoreData logging component and reduces the chattiness of the debug logging level for Core Data Network events.
This commit is contained in:
@@ -35,13 +35,12 @@
|
||||
|
||||
// Set Logging Component
|
||||
#undef RKLogComponent
|
||||
#define RKLogComponent RKlcl_cRestKitCoreData
|
||||
#define RKLogComponent RKlcl_cRestKitNetworkCoreData
|
||||
|
||||
@interface RKEntityMappingEvent : NSObject
|
||||
@property (nonatomic, copy) id rootKey;
|
||||
@property (nonatomic, copy) NSString *keyPath;
|
||||
@property (nonatomic, strong) RKEntityMapping *entityMapping;
|
||||
@property (nonatomic, readonly) BOOL canSkipMapping;
|
||||
|
||||
+ (instancetype)eventWithRootKey:(id)rootKey keyPath:(NSString *)keyPath entityMapping:(RKEntityMapping *)entityMapping;
|
||||
@end
|
||||
@@ -299,6 +298,8 @@ static NSURL *RKRelativeURLFromURLAndResponseDescriptors(NSURL *URL, NSArray *re
|
||||
@property (nonatomic, strong, readwrite) RKMappingResult *mappingResult;
|
||||
@property (nonatomic, copy) id (^willMapDeserializedResponseBlock)(id deserializedResponseBody);
|
||||
@property (nonatomic, strong) NSArray *entityMappingEvents;
|
||||
|
||||
@property (nonatomic, strong) NSCachedURLResponse *cachedResponse;
|
||||
@end
|
||||
|
||||
@implementation RKManagedObjectRequestOperation
|
||||
@@ -312,6 +313,7 @@ static NSURL *RKRelativeURLFromURLAndResponseDescriptors(NSURL *URL, NSArray *re
|
||||
if (self) {
|
||||
self.savesToPersistentStore = YES;
|
||||
self.deletesOrphanedObjects = YES;
|
||||
self.cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:requestOperation.request];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -372,14 +374,31 @@ static NSURL *RKRelativeURLFromURLAndResponseDescriptors(NSURL *URL, NSArray *re
|
||||
// RKResponseHasBeenMappedCacheUserInfoKey is stored by RKObjectRequestOperation
|
||||
- (BOOL)canSkipMapping
|
||||
{
|
||||
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:self.HTTPRequestOperation.request];
|
||||
// Is the request cacheable
|
||||
if (!self.cachedResponse) return NO;
|
||||
NSURLRequest *request = self.HTTPRequestOperation.request;
|
||||
if (! [[request HTTPMethod] isEqualToString:@"GET"] && ! [[request HTTPMethod] isEqualToString:@"HEAD"]) return NO;
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)self.HTTPRequestOperation.response;
|
||||
if (! [RKCacheableStatusCodes() containsIndex:response.statusCode]) return NO;
|
||||
|
||||
// Check for a change in the Etag
|
||||
NSString *cachedEtag = [[(NSHTTPURLResponse *)[self.cachedResponse response] allHeaderFields] objectForKey:@"Etag"];
|
||||
NSString *responseEtag = [[response allHeaderFields] objectForKey:@"Etag"];
|
||||
if (! [cachedEtag isEqualToString:responseEtag]) return NO;
|
||||
|
||||
// Response data has changed
|
||||
NSData *responseData = self.HTTPRequestOperation.responseData;
|
||||
if (! [responseData isEqualToData:[self.cachedResponse data]]) return NO;
|
||||
|
||||
// Check that we have mapped this response previously
|
||||
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
|
||||
return [[cachedResponse.userInfo objectForKey:RKResponseHasBeenMappedCacheUserInfoKey] boolValue];
|
||||
}
|
||||
|
||||
- (RKMappingResult *)performMappingOnResponse:(NSError **)error
|
||||
{
|
||||
if (self.canSkipMapping) {
|
||||
RKLogDebug(@"Managed object mapping requested for cached response: skipping mapping...");
|
||||
if ([self canSkipMapping]) {
|
||||
RKLogDebug(@"Managed object mapping requested for cached response which was previously mapped: skipping...");
|
||||
NSURL *URL = RKRelativeURLFromURLAndResponseDescriptors(self.HTTPRequestOperation.response.URL, self.responseDescriptors);
|
||||
NSArray *fetchRequests = RKArrayOfFetchRequestFromBlocksWithURL(self.fetchRequestBlocks, URL);
|
||||
NSMutableArray *managedObjects = [NSMutableArray array];
|
||||
@@ -470,7 +489,7 @@ static NSURL *RKRelativeURLFromURLAndResponseDescriptors(NSURL *URL, NSArray *re
|
||||
RKLogTrace(@"Fetched local objects matching URL '%@' with fetch request '%@': %@", URL, fetchRequest, _blockObjects);
|
||||
[localObjects addObjectsFromArray:_blockObjects];
|
||||
} else {
|
||||
RKLogDebug(@"Fetch request block %@ returned nil fetch request for URL: '%@'", fetchRequestBlock, URL);
|
||||
RKLogTrace(@"Fetch request block %@ returned nil fetch request for URL: '%@'", fetchRequestBlock, URL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +508,7 @@ static NSURL *RKRelativeURLFromURLAndResponseDescriptors(NSURL *URL, NSArray *re
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (self.canSkipMapping) {
|
||||
if ([self canSkipMapping]) {
|
||||
RKLogDebug(@"Skipping deletion of orphaned objects: 304 (Not Modified) status code encountered");
|
||||
return YES;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user