Created
April 9, 2013 13:04
-
-
Save maxhuk/5345539 to your computer and use it in GitHub Desktop.
Cancelable NSURLConnection with exact timeout.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AsyncURLConnection.h | |
// | |
// Created by Maksym Huk on 10/31/12. | |
// Copyright (c) 2012 Maksym Huk. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
// Send request with exact timeout | |
@interface AsyncURLConnection : NSObject | |
+ (AsyncURLConnection *)connectionWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler; | |
- (void)connectionWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler; | |
- (void)cancel; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AsyncURLConnection.m | |
// | |
// Created by Maksym Huk on 10/31/12. | |
// Copyright (c) 2012 Maksym Huk. All rights reserved. | |
// | |
#import "AsyncURLConnection.h" | |
@interface AsyncURLConnection () <NSURLConnectionDataDelegate> | |
@end | |
@implementation AsyncURLConnection | |
{ | |
NSURLConnection *_connection; | |
NSTimer *_timer; | |
void (^_handler)(NSURLResponse*, NSData*, NSError*); | |
NSURLResponse *_response; | |
NSMutableData *_data; | |
} | |
- (void)connectionWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler | |
{ | |
_handler = handler; | |
_response = nil; | |
_data = [NSMutableData data]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
_timer = [NSTimer timerWithTimeInterval:request.timeoutInterval | |
target:self | |
selector:@selector(requestDidTimeout:) | |
userInfo:nil | |
repeats:NO]; | |
_connection = [NSURLConnection connectionWithRequest:request delegate:self]; | |
}); | |
} | |
- (void)cancel | |
{ | |
[_connection cancel]; | |
} | |
+ (AsyncURLConnection *)connectionWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler | |
{ | |
AsyncURLConnection *connection = [[AsyncURLConnection alloc] init]; | |
[connection connectionWithRequest:request completionHandler:handler]; | |
return connection; | |
} | |
- (void)requestDidTimeout:(NSTimer *)timer | |
{ | |
NSURL *url = _connection.currentRequest.URL; | |
[_connection cancel]; | |
_connection = nil; | |
_timer = nil; | |
_handler(_response, _data, [NSError errorWithDomain:NSPOSIXErrorDomain code:ETIMEDOUT userInfo:@{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Connection timed out to URL: %@", url] }]); | |
} | |
#pragma mark - NSURLConnectionDataDelegate | |
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error | |
{ | |
[_timer invalidate]; | |
_timer = nil; | |
_handler(_response, _data, error); | |
} | |
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response | |
{ | |
_response = response; | |
} | |
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data | |
{ | |
[_data appendData:data]; | |
} | |
- (void)connectionDidFinishLoading:(NSURLConnection *)connection | |
{ | |
[_timer invalidate]; | |
_timer = nil; | |
_handler(_response, _data, nil); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment