Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add support for timing out an RKRequest via a timeoutTimer and a time…

…out property.

* Add timeoutInterval property on RKRequest with a default value of 120.0
* Add timeout method that is called by the timer when the timeout interval has been exceeded to cancel the request and return an error via didFailLoadWithError:
* Add invalidateTimeoutTimer method that is called by RKResponse when the NSURLConnection begins receiving data.
* Add call to invalidateTimeoutTimer in RKRequest cancelAndInformDelegate: so we don't have a dangling timer.
* Add timer creation to sendAsynchronously and sendSynchronously
  • Loading branch information...
commit 90716335f5c26a6bfe30c8ac5853277e1e7e8e64 1 parent 8051fbd
Brian Morton bmorton authored blakewatters committed
Showing with 43 additions and 0 deletions.
  1. +21 −0 Code/Network/RKRequest.h
  2. +22 −0 Code/Network/RKRequest.m
21 Code/Network/RKRequest.h
View
@@ -121,6 +121,7 @@ typedef enum {
NSTimeInterval _cacheTimeoutInterval;
RKRequestQueue *_queue;
RKReachabilityObserver *_reachabilityObserver;
+ NSTimer *_timeoutTimer;
#if TARGET_OS_IPHONE
RKRequestBackgroundPolicy _backgroundPolicy;
@@ -184,6 +185,14 @@ typedef enum {
@property (nonatomic, assign) RKRequestQueue *queue;
/**
+ * The timeout interval within which the request should be cancelled
+ * if no data has been received
+ *
+ * @default 120.0
+ */
+@property (nonatomic, assign) NSTimeInterval timeoutInterval;
+
+/**
* The policy to take on transition to the background (iOS 4.x and higher only)
*
* Default: RKRequestBackgroundPolicyCancel
@@ -381,6 +390,18 @@ typedef enum {
- (void)cancel;
/**
+ * Cancels request due to connection timeout exceeded.
+ * This will return an RKRequestConnectionTimeoutError via didFailLoadWithError:
+ */
+- (void)timeout;
+
+/**
+ * Invalidates the timeout timer.
+ * Called by RKResponse when the NSURLConnection begins receiving data.
+ */
+- (void)invalidateTimeoutTimer;
+
+/**
* Returns YES when this is a GET request
*/
- (BOOL)isGET;
22 Code/Network/RKRequest.m
View
@@ -61,6 +61,7 @@ @implementation RKRequest
@synthesize OAuth2AccessToken = _OAuth2AccessToken;
@synthesize OAuth2RefreshToken = _OAuth2RefreshToken;
@synthesize queue = _queue;
+@synthesize timeoutInterval = _timeoutInterval;
@synthesize reachabilityObserver = _reachabilityObserver;
#if TARGET_OS_IPHONE
@@ -79,6 +80,7 @@ - (id)initWithURL:(NSURL*)URL {
_authenticationType = RKRequestAuthenticationTypeNone;
_cachePolicy = RKRequestCachePolicyDefault;
_cacheTimeoutInterval = 0;
+ _timeoutInterval = 120.0;
}
return self;
}
@@ -323,6 +325,7 @@ - (void)cancelAndInformDelegate:(BOOL)informDelegate {
[_connection cancel];
[_connection release];
_connection = nil;
+ [self invalidateTimeoutTimer];
_isLoading = NO;
if (informDelegate && [_delegate respondsToSelector:@selector(requestDidCancelLoad:)]) {
@@ -420,6 +423,7 @@ - (void)sendAsynchronously {
_isLoading = YES;
[self didFinishLoad:response];
} else if ([self shouldDispatchRequest]) {
+ _timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:self.timeoutInterval target:self selector:@selector(timeout) userInfo:nil repeats:NO];
#if TARGET_OS_IPHONE
// Background Request Policy support
UIApplication* app = [UIApplication sharedApplication];
@@ -490,6 +494,8 @@ - (RKResponse*)sendSynchronously {
[self didFinishLoad:response];
} else if ([self shouldDispatchRequest]) {
RKLogDebug(@"Sending synchronous %@ request to URL %@.", [self HTTPMethod], [[self URL] absoluteString]);
+ _timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:self.timeoutInterval target:self selector:@selector(timeout) userInfo:nil repeats:NO];
+
if (![self prepareURLRequest]) {
// TODO: Logging
return nil;
@@ -537,6 +543,22 @@ - (void)cancel {
[self cancelAndInformDelegate:YES];
}
+- (void)timeout {
+ [self cancelAndInformDelegate:NO];
+ RKLogError(@"Failed to send request to %@ due to connection timeout. Timeout interval = %f", [[self URL] absoluteString], self.timeoutInterval);
+ NSString* errorMessage = [NSString stringWithFormat:@"The client timed out connecting to the resource at %@", [[self URL] absoluteString]];
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ errorMessage, NSLocalizedDescriptionKey,
+ nil];
+ NSError* error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKRequestConnectionTimeoutError userInfo:userInfo];
+ [self didFailLoadWithError:error];
+}
+
+- (void)invalidateTimeoutTimer {
+ [_timeoutTimer invalidate];
+ _timeoutTimer = nil;
+}
+
- (void)didFailLoadWithError:(NSError*)error {
if (_cachePolicy & RKRequestCachePolicyLoadOnError &&
[self.cache hasResponseForRequest:self]) {
Please sign in to comment.
Something went wrong with that request. Please try again.