mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-23 12:27:52 +08:00
removed duplicate delegates on RKObjectLoader; inverted control for communicating request completion from RKResponse to RKRequest; added state tracking to RKRequest for loaded and loading states; changed queue processing logic to check request states before firing new requests; removed retains of RKObjectLoader from RKRequestTTModel since our queue is handling retains for all asynchronous RKRequest flavors; added separate state tracking to RKRequestTTModel since there are subtle differences between the meaning of loaded/loading in Three20 versus our RKRequest states; removed delegate forwarding code from RKObjectLoader since it is no longer an RKRequestDelegate (which was quite ugly to begin with); removed unnecessary error contructor for RKResponse that was only being used to fire delegate callbacks when an RKRequest failed to fire in offline mode; added TODOs to deep-dive into synchronous request handling
This commit is contained in:
@@ -35,6 +35,8 @@ typedef enum RKRequestMethod {
|
||||
NSString* _username;
|
||||
NSString* _password;
|
||||
RKRequestMethod _method;
|
||||
BOOL _isLoading;
|
||||
BOOL _isLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,6 +125,18 @@ typedef enum RKRequestMethod {
|
||||
*/
|
||||
- (RKResponse*)sendSynchronously;
|
||||
|
||||
/**
|
||||
* Callback performed to notify the request that the underlying NSURLConnection
|
||||
* has failed with an error.
|
||||
*/
|
||||
- (void)didFailLoadWithError:(NSError*)error;
|
||||
|
||||
/**
|
||||
* Callback performed to notify the request that the underlying NSURLConnection
|
||||
* has completed with a response.
|
||||
*/
|
||||
- (void)didFinishLoad:(RKResponse*)response;
|
||||
|
||||
/**
|
||||
* Cancels the underlying URL connection
|
||||
*/
|
||||
@@ -148,6 +162,16 @@ typedef enum RKRequestMethod {
|
||||
*/
|
||||
- (BOOL)isDELETE;
|
||||
|
||||
/**
|
||||
* Returns YES when this request is in-progress
|
||||
*/
|
||||
- (BOOL)isLoading;
|
||||
|
||||
/**
|
||||
* Returns YES when this request has been completed
|
||||
*/
|
||||
- (BOOL)isLoaded;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
params = _params, userData = _userData, username = _username, password = _password, method = _method;
|
||||
|
||||
+ (RKRequest*)requestWithURL:(NSURL*)URL delegate:(id)delegate {
|
||||
RKRequest* request = [[RKRequest alloc] initWithURL:URL delegate:delegate];
|
||||
[request autorelease];
|
||||
|
||||
return request;
|
||||
return [[[RKRequest alloc] initWithURL:URL delegate:delegate] autorelease];
|
||||
}
|
||||
|
||||
- (id)initWithURL:(NSURL*)URL {
|
||||
@@ -32,8 +29,9 @@
|
||||
_URL = [URL retain];
|
||||
_URLRequest = [[NSMutableURLRequest alloc] initWithURL:_URL];
|
||||
_connection = nil;
|
||||
_isLoading = NO;
|
||||
_isLoaded = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -41,20 +39,28 @@
|
||||
if (self = [self initWithURL:URL]) {
|
||||
_delegate = delegate;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
self.delegate = nil;
|
||||
[_connection cancel];
|
||||
[_connection release];
|
||||
_connection = nil;
|
||||
[_userData release];
|
||||
_userData = nil;
|
||||
[_URL release];
|
||||
_URL = nil;
|
||||
[_URLRequest release];
|
||||
_URLRequest = nil;
|
||||
[_params release];
|
||||
_params = nil;
|
||||
[_additionalHTTPHeaders release];
|
||||
_additionalHTTPHeaders = nil;
|
||||
[_username release];
|
||||
_username = nil;
|
||||
[_password release];
|
||||
_password = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -131,6 +137,7 @@
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", sentAt, @"sentAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestSentNotification object:self userInfo:userInfo];
|
||||
|
||||
_isLoading = YES;
|
||||
RKResponse* response = [[[RKResponse alloc] initWithRequest:self] autorelease];
|
||||
_connection = [[NSURLConnection connectionWithRequest:_URLRequest delegate:response] retain];
|
||||
} else {
|
||||
@@ -139,7 +146,7 @@
|
||||
errorMessage, NSLocalizedDescriptionKey,
|
||||
nil];
|
||||
NSError* error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
|
||||
RKResponse* response = [[[RKResponse alloc] initWithRequest:self error:error] autorelease];
|
||||
[self didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +165,7 @@
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", sentAt, @"sentAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestSentNotification object:self userInfo:userInfo];
|
||||
|
||||
_isLoading = YES;
|
||||
payload = [NSURLConnection sendSynchronousRequest:_URLRequest returningResponse:&URLResponse error:&error];
|
||||
response = [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
|
||||
} else {
|
||||
@@ -166,6 +174,9 @@
|
||||
errorMessage, NSLocalizedDescriptionKey,
|
||||
nil];
|
||||
error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
|
||||
[self didFailLoadWithError:error];
|
||||
|
||||
// TODO: Is this needed here? Or can we just return a nil response and everyone will be happy??
|
||||
response = [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
|
||||
}
|
||||
|
||||
@@ -176,6 +187,33 @@
|
||||
[_connection cancel];
|
||||
[_connection release];
|
||||
_connection = nil;
|
||||
_isLoading = NO;
|
||||
}
|
||||
|
||||
- (void)didFailLoadWithError:(NSError*)error {
|
||||
_isLoading = NO;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[_delegate request:self didFailLoadWithError:error];
|
||||
}
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod",
|
||||
[self URL], @"URL", receivedAt, @"receivedAt", error, @"error", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestFailedWithErrorNotification object:self userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (void)didFinishLoad:(RKResponse*)response {
|
||||
_isLoading = NO;
|
||||
_isLoaded = YES;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(requestDidFinishLoad:withResponse:)]) {
|
||||
[_delegate requestDidFinishLoad:self withResponse:response];
|
||||
}
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", receivedAt, @"receivedAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:response userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (BOOL)isGET {
|
||||
@@ -194,6 +232,14 @@
|
||||
return _method == RKRequestMethodDELETE;
|
||||
}
|
||||
|
||||
- (BOOL)isLoading {
|
||||
return _isLoading;
|
||||
}
|
||||
|
||||
- (BOOL)isLoaded {
|
||||
return _isLoaded;
|
||||
}
|
||||
|
||||
- (NSString*)resourcePath {
|
||||
NSString* resourcePath = nil;
|
||||
if ([self.URL isKindOfClass:[RKURL class]]) {
|
||||
|
||||
@@ -76,12 +76,11 @@ static const NSInteger kMaxConcurrentLoads = 5;
|
||||
- (void)loadNextInQueue {
|
||||
_queueTimer = nil;
|
||||
|
||||
for (int i = _totalLoading;
|
||||
i < kMaxConcurrentLoads && i < _requests.count;
|
||||
++i) {
|
||||
RKRequest* request = [_requests objectAtIndex:i];
|
||||
++_totalLoading;
|
||||
[self dispatchRequest:request];
|
||||
for (RKRequest* request in _requests) {
|
||||
if (![request isLoading] && ![request isLoaded] && _totalLoading < kMaxConcurrentLoads) {
|
||||
++_totalLoading;
|
||||
[self dispatchRequest:request];
|
||||
}
|
||||
}
|
||||
|
||||
if (_requests.count && !_suspended) {
|
||||
@@ -106,27 +105,36 @@ static const NSInteger kMaxConcurrentLoads = 5;
|
||||
[self loadNextInQueue];
|
||||
}
|
||||
|
||||
- (void)cancelRequest:(RKRequest*)request {
|
||||
if ([_requests containsObject:request]) {
|
||||
- (void)cancelRequest:(RKRequest*)request loadNext:(BOOL)loadNext {
|
||||
if ([_requests containsObject:request] && ![request isLoaded]) {
|
||||
[request cancel];
|
||||
|
||||
NSLog(@"Request cancelled and removed: URL=%@", [request URL]);
|
||||
|
||||
[_requests removeObject:request];
|
||||
_totalLoading--;
|
||||
[self loadNextInQueue];
|
||||
|
||||
if (loadNext) {
|
||||
[self loadNextInQueue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelRequest:(RKRequest*)request {
|
||||
[self cancelRequest:request loadNext:YES];
|
||||
}
|
||||
|
||||
- (void)cancelRequestsWithDelegate:(NSObject<RKRequestDelegate>*)delegate {
|
||||
for (RKRequest* request in _requests) {
|
||||
if (request.delegate && request.delegate == delegate) {
|
||||
[request cancel];
|
||||
[self cancelRequest:request];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelAllRequests {
|
||||
for (RKRequest* request in [[[_requests copy] autorelease] objectEnumerator]) {
|
||||
[request cancel];
|
||||
[self cancelRequest:request loadNext:NO];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +145,6 @@ static const NSInteger kMaxConcurrentLoads = 5;
|
||||
- (void)responseDidLoad:(NSNotification*)notification {
|
||||
if (notification.object && [notification.object isKindOfClass:[RKResponse class]]) {
|
||||
RKResponse* response = (RKResponse*)notification.object;
|
||||
[_requests removeObject:[response request]];
|
||||
_totalLoading--;
|
||||
[self loadNextInQueue];
|
||||
|
||||
NSError* error = (NSError*)[notification.userInfo objectForKey:@"error"];
|
||||
if (error) {
|
||||
@@ -147,6 +152,11 @@ static const NSInteger kMaxConcurrentLoads = 5;
|
||||
} else {
|
||||
NSLog(@"Request completed and removed: URL=%@", [[response request] URL]);
|
||||
}
|
||||
|
||||
[_requests removeObject:[response request]];
|
||||
_totalLoading--;
|
||||
|
||||
[self loadNextInQueue];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,13 +57,6 @@
|
||||
*/
|
||||
- (id)initWithRequest:(RKRequest*)request;
|
||||
|
||||
/**
|
||||
* Initialize a new response object for a REST request along
|
||||
* with an error object, allowing for failures prior to an asynchronous
|
||||
* request being sent.
|
||||
*/
|
||||
- (id)initWithRequest:(RKRequest*)request error:(NSError*)error;
|
||||
|
||||
/**
|
||||
* Initializes a response object from the results of a synchronous request
|
||||
*/
|
||||
|
||||
@@ -34,20 +34,11 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithRequest:(RKRequest*)request error:(NSError*)error {
|
||||
if (self = [self initWithRequest:request]) {
|
||||
_failureError = [error retain];
|
||||
if ([[_request delegate] respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[[_request delegate] request:_request didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithSynchronousRequest:(RKRequest*)request URLResponse:(NSURLResponse*)URLResponse body:(NSData*)body error:(NSError*)error {
|
||||
if (self = [super init]) {
|
||||
_request = [request retain];
|
||||
// TODO: Does the lack of retain here cause problems with synchronous requests, since they
|
||||
// are not being retained by the RKRequestQueue??
|
||||
_request = request;
|
||||
_httpURLResponse = [URLResponse retain];
|
||||
_failureError = [error retain];
|
||||
_body = [body retain];
|
||||
@@ -94,25 +85,12 @@
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
if ([[_request delegate] respondsToSelector:@selector(requestDidFinishLoad:withResponse:)]) {
|
||||
[[_request delegate] requestDidFinishLoad:_request withResponse:self];
|
||||
}
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[_request HTTPMethod], @"HTTPMethod", [_request URL], @"URL", receivedAt, @"receivedAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:self userInfo:userInfo];
|
||||
[_request didFinishLoad:self];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
_failureError = [error retain];
|
||||
if ([[_request delegate] respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[[_request delegate] request:_request didFailLoadWithError:error];
|
||||
}
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[_request HTTPMethod], @"HTTPMethod",
|
||||
[_request URL], @"URL", receivedAt, @"receivedAt", error, @"error", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestFailedWithErrorNotification object:_request userInfo:userInfo];
|
||||
[_request didFailLoadWithError:_failureError];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
/**
|
||||
* Wraps a request/response cycle and loads a remote object representation into local domain objects
|
||||
*/
|
||||
@interface RKObjectLoader : RKRequest <RKRequestDelegate> {
|
||||
@interface RKObjectLoader : RKRequest {
|
||||
RKObjectMapper* _mapper;
|
||||
NSObject<RKObjectLoaderDelegate>* _objectLoaderDelegate;
|
||||
RKResponse* _response;
|
||||
NSObject<RKObjectMappable>* _targetObject;
|
||||
Class<RKObjectMappable> _objectClass;
|
||||
@@ -56,14 +55,6 @@
|
||||
*/
|
||||
@property (nonatomic, readonly) RKObjectMapper* mapper;
|
||||
|
||||
/**
|
||||
* The object to be invoked with the loaded models
|
||||
*
|
||||
* If this object implements life-cycle methods from the RKRequestDelegate protocol,
|
||||
* events from the request will be forwarded back.
|
||||
*/
|
||||
@property (nonatomic, assign) NSObject<RKObjectLoaderDelegate>* objectLoaderDelegate;
|
||||
|
||||
/**
|
||||
* The underlying response object for this loader
|
||||
*/
|
||||
|
||||
@@ -13,24 +13,20 @@
|
||||
#import "Errors.h"
|
||||
#import "RKManagedObject.h"
|
||||
#import "RKURL.h"
|
||||
|
||||
@interface RKObjectLoader (Private)
|
||||
- (void)loadObjectsFromResponse:(RKResponse*)response;
|
||||
@end
|
||||
#import "RKNotifications.h"
|
||||
|
||||
@implementation RKObjectLoader
|
||||
|
||||
@synthesize mapper = _mapper, objectLoaderDelegate = _objectLoaderDelegate, response = _response,
|
||||
objectClass = _objectClass, targetObject = _targetObject, keyPath = _keyPath, managedObjectStore = _managedObjectStore;
|
||||
@synthesize mapper = _mapper, response = _response, objectClass = _objectClass, targetObject = _targetObject,
|
||||
keyPath = _keyPath, managedObjectStore = _managedObjectStore;
|
||||
|
||||
+ (id)loaderWithResourcePath:(NSString*)resourcePath mapper:(RKObjectMapper*)mapper delegate:(NSObject<RKObjectLoaderDelegate>*)delegate {
|
||||
return [[[self alloc] initWithResourcePath:resourcePath mapper:mapper delegate:delegate] autorelease];
|
||||
}
|
||||
|
||||
- (id)initWithResourcePath:(NSString*)resourcePath mapper:(RKObjectMapper*)mapper delegate:(NSObject<RKObjectLoaderDelegate>*)delegate {
|
||||
if (self = [self initWithURL:[[RKClient sharedClient] URLForResourcePath:resourcePath] delegate:self]) {
|
||||
if (self = [self initWithURL:[[RKClient sharedClient] URLForResourcePath:resourcePath] delegate:delegate]) {
|
||||
_mapper = [mapper retain];
|
||||
self.objectLoaderDelegate = delegate;
|
||||
self.managedObjectStore = nil;
|
||||
_targetObjectID = nil;
|
||||
|
||||
@@ -40,15 +36,17 @@
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
self.delegate = nil;
|
||||
self.objectLoaderDelegate = nil;
|
||||
[self cancel];
|
||||
[_mapper release];
|
||||
_mapper = nil;
|
||||
[_response release];
|
||||
_response = nil;
|
||||
[_keyPath release];
|
||||
self.managedObjectStore = nil;
|
||||
_keyPath = nil;
|
||||
[_targetObject release];
|
||||
_targetObject = nil;
|
||||
[_targetObjectID release];
|
||||
_targetObjectID = nil;
|
||||
_targetObjectID = nil;
|
||||
self.managedObjectStore = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -68,16 +66,25 @@
|
||||
|
||||
#pragma mark Response Processing
|
||||
|
||||
- (void)responseProcessingComplete {
|
||||
_isLoading = NO;
|
||||
_isLoaded = YES;
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", receivedAt, @"receivedAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:_response userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (BOOL)encounteredErrorWhileProcessingRequest:(RKResponse*)response {
|
||||
if ([response isFailure]) {
|
||||
[_objectLoaderDelegate objectLoader:self didFailWithError:response.failureError];
|
||||
[(NSObject<RKObjectLoaderDelegate>*)_delegate objectLoader:self didFailWithError:response.failureError];
|
||||
return YES;
|
||||
} else if ([response isError]) {
|
||||
if ([response isJSON]) {
|
||||
[_objectLoaderDelegate objectLoader:self didFailWithError:[_mapper parseErrorFromString:[response bodyAsString]]];
|
||||
[(NSObject<RKObjectLoaderDelegate>*)_delegate objectLoader:self didFailWithError:[_mapper parseErrorFromString:[response bodyAsString]]];
|
||||
} else {
|
||||
if ([_objectLoaderDelegate respondsToSelector:@selector(objectLoaderDidLoadUnexpectedResponse:)]) {
|
||||
[_objectLoaderDelegate objectLoaderDidLoadUnexpectedResponse:self];
|
||||
if ([_delegate respondsToSelector:@selector(objectLoaderDidLoadUnexpectedResponse:)]) {
|
||||
[(NSObject<RKObjectLoaderDelegate>*)_delegate objectLoaderDidLoadUnexpectedResponse:self];
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
@@ -101,7 +108,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
[_objectLoaderDelegate objectLoader:self didLoadObjects:[NSArray arrayWithArray:objects]];
|
||||
[(NSObject<RKObjectLoaderDelegate>*)_delegate objectLoader:self didLoadObjects:[NSArray arrayWithArray:objects]];
|
||||
|
||||
[self responseProcessingComplete];
|
||||
}
|
||||
|
||||
- (void)informDelegateOfObjectLoadErrorWithInfoDictionary:(NSDictionary*)dictionary {
|
||||
@@ -115,7 +124,9 @@
|
||||
nil];
|
||||
NSError *rkError = [NSError errorWithDomain:RKRestKitErrorDomain code:RKObjectLoaderRemoteSystemError userInfo:userInfo];
|
||||
|
||||
[_objectLoaderDelegate objectLoader:self didFailWithError:rkError];
|
||||
[(NSObject<RKObjectLoaderDelegate>*)_delegate objectLoader:self didFailWithError:rkError];
|
||||
|
||||
[self responseProcessingComplete];
|
||||
}
|
||||
|
||||
|
||||
@@ -190,46 +201,26 @@
|
||||
[pool release];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RKRequestDelegate
|
||||
//
|
||||
// If our delegate responds to the messages, forward them back...
|
||||
|
||||
- (void)requestDidStartLoad:(RKRequest*)request {
|
||||
if ([_objectLoaderDelegate respondsToSelector:@selector(requestDidStartLoad:)]) {
|
||||
[_objectLoaderDelegate requestDidStartLoad:request];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)requestDidFinishLoad:(RKRequest*)request withResponse:(RKResponse*)response {
|
||||
- (void)didFinishLoad:(RKResponse*)response {
|
||||
_response = [response retain];
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(requestDidFinishLoad:withResponse:)]) {
|
||||
[_delegate requestDidFinishLoad:self withResponse:response];
|
||||
}
|
||||
|
||||
if (NO == [self encounteredErrorWhileProcessingRequest:response]) {
|
||||
// TODO: When other mapping formats are supported, unwind this assumption...
|
||||
if ([response isSuccessful] && [response isJSON]) {
|
||||
[self performSelectorInBackground:@selector(processLoadModelsInBackground:) withObject:response];
|
||||
} else {
|
||||
NSLog(@"Encountered unexpected response code: %d (MIME Type: %@)", response.statusCode, response.MIMEType);
|
||||
if ([_objectLoaderDelegate respondsToSelector:@selector(objectLoaderDidLoadUnexpectedResponse:)]) {
|
||||
[_objectLoaderDelegate objectLoaderDidLoadUnexpectedResponse:self];
|
||||
if ([_delegate respondsToSelector:@selector(objectLoaderDidLoadUnexpectedResponse:)]) {
|
||||
[(NSObject<RKObjectLoaderDelegate>*)_delegate objectLoaderDidLoadUnexpectedResponse:self];
|
||||
}
|
||||
[self responseProcessingComplete];
|
||||
}
|
||||
}
|
||||
|
||||
if ([_objectLoaderDelegate respondsToSelector:@selector(requestDidFinishLoad:)]) {
|
||||
[(NSObject<RKRequestDelegate>*)_objectLoaderDelegate requestDidFinishLoad:request withResponse:response];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError*)error {
|
||||
if ([_objectLoaderDelegate respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[(NSObject<RKRequestDelegate>*)_objectLoaderDelegate request:request didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)request:(RKRequest*)request didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
|
||||
if ([_objectLoaderDelegate respondsToSelector:@selector(request:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)]) {
|
||||
[(NSObject<RKRequestDelegate>*)_objectLoaderDelegate request:request didSendBodyData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite];
|
||||
} else {
|
||||
[self responseProcessingComplete];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
@interface RKRequestTTModel : TTModel <RKObjectLoaderDelegate> {
|
||||
NSArray *_objects;
|
||||
BOOL _loaded;
|
||||
BOOL _isLoaded;
|
||||
BOOL _isLoading;
|
||||
BOOL _cacheLoaded;
|
||||
|
||||
NSString* _resourcePath;
|
||||
NSDictionary* _params;
|
||||
RKRequestMethod _method;
|
||||
RKObjectLoader* _objectLoader;
|
||||
Class _objectClass;
|
||||
NSString* _keyPath;
|
||||
|
||||
@@ -38,12 +38,6 @@
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString* resourcePath;
|
||||
|
||||
/**
|
||||
* The RKObjectLoader, created when this model is loading data
|
||||
* from the resourcePath.
|
||||
*/
|
||||
@property (nonatomic, readonly) RKObjectLoader* objectLoader;
|
||||
|
||||
/**
|
||||
* The NSDate object representing the last time this model was loaded.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,6 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
@synthesize objects = _objects;
|
||||
@synthesize resourcePath = _resourcePath;
|
||||
@synthesize params = _params;
|
||||
@synthesize objectLoader = _objectLoader;
|
||||
@synthesize method = _method;
|
||||
@synthesize refreshRate = _refreshRate;
|
||||
|
||||
@@ -97,18 +96,15 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
self.params = nil;
|
||||
_cacheLoaded = NO;
|
||||
_objects = nil;
|
||||
_loaded = NO;
|
||||
_isLoaded = NO;
|
||||
_isLoading = NO;
|
||||
_resourcePath = nil;
|
||||
_objectLoader = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_objectLoader setObjectLoaderDelegate:nil];
|
||||
[[RKRequestQueue sharedQueue] cancelRequest:_objectLoader];
|
||||
[_objectLoader release];
|
||||
_objectLoader = nil;
|
||||
[[RKRequestQueue sharedQueue] cancelRequestsWithDelegate:self];
|
||||
[_objects release];
|
||||
_objects = nil;
|
||||
[_objectClass release];
|
||||
@@ -123,11 +119,11 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
// TTModel
|
||||
|
||||
- (BOOL)isLoaded {
|
||||
return _loaded;
|
||||
return _isLoaded;
|
||||
}
|
||||
|
||||
- (BOOL)isLoading {
|
||||
return nil != _objectLoader;
|
||||
return _isLoading;
|
||||
}
|
||||
|
||||
- (BOOL)isLoadingMore {
|
||||
@@ -139,9 +135,7 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[[RKRequestQueue sharedQueue] cancelRequest:_objectLoader];
|
||||
[_objectLoader release];
|
||||
_objectLoader = nil;
|
||||
[[RKRequestQueue sharedQueue] cancelRequestsWithDelegate:self];
|
||||
[self didCancelLoad];
|
||||
}
|
||||
|
||||
@@ -164,30 +158,24 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
|
||||
#pragma mark RKModelLoaderDelegate
|
||||
|
||||
// This callback is invoked after the request has been fully serviced. Finish the load here.
|
||||
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
|
||||
if (objectLoader == _objectLoader) {
|
||||
[_objectLoader release];
|
||||
_objectLoader = nil;
|
||||
[self modelsDidLoad:objects];
|
||||
}
|
||||
_isLoading = NO;
|
||||
[self modelsDidLoad:objects];
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
|
||||
if (objectLoader == _objectLoader) {
|
||||
[_objectLoader release];
|
||||
_objectLoader = nil;
|
||||
}
|
||||
_isLoading = NO;
|
||||
[self didFailLoadWithError:error];
|
||||
if ([self errorWarrantsOptionToGoOffline:error]) {
|
||||
[self showAlertWithOptionToGoOfflineForError:error];
|
||||
} else {
|
||||
[self didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)objectLoaderDidLoadUnexpectedResponse:(RKObjectLoader*)objectLoader {
|
||||
[objectLoader release];
|
||||
_objectLoader = nil;
|
||||
_isLoading = NO;
|
||||
|
||||
// TODO: Passing a nil error here does nothing for Three20. Need to construct our
|
||||
// own error here to make Three20 happy??
|
||||
[self didFailLoadWithError:nil];
|
||||
}
|
||||
|
||||
@@ -241,7 +229,7 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
_objects = nil;
|
||||
|
||||
_objects = models;
|
||||
_loaded = YES;
|
||||
_isLoaded = YES;
|
||||
|
||||
[self saveLoadedTime];
|
||||
[self didFinishLoad];
|
||||
@@ -260,14 +248,15 @@ static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTi
|
||||
}
|
||||
|
||||
if (!store.managedObjectCache || !cacheFetchRequests || _cacheLoaded || [cachedObjects count] == 0) {
|
||||
_objectLoader = [[[RKObjectManager sharedManager] objectLoaderWithResourcePath:_resourcePath delegate:self] retain];
|
||||
_objectLoader.method = self.method;
|
||||
_objectLoader.objectClass = _objectClass;
|
||||
_objectLoader.keyPath = _keyPath;
|
||||
_objectLoader.params = self.params;
|
||||
RKObjectLoader* objectLoader = [[[RKObjectManager sharedManager] objectLoaderWithResourcePath:_resourcePath delegate:self] retain];
|
||||
objectLoader.method = self.method;
|
||||
objectLoader.objectClass = _objectClass;
|
||||
objectLoader.keyPath = _keyPath;
|
||||
objectLoader.params = self.params;
|
||||
|
||||
_isLoading = YES;
|
||||
[self didStartLoad];
|
||||
[_objectLoader send];
|
||||
[objectLoader send];
|
||||
|
||||
} else if (cacheFetchRequests && !_cacheLoaded) {
|
||||
_cacheLoaded = YES;
|
||||
|
||||
Reference in New Issue
Block a user