Created
September 14, 2010 06:36
-
-
Save zoul/578636 to your computer and use it in GitHub Desktop.
Asynchronous NSURLConnection in concurrent NSOperation
This file contains hidden or 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
@interface DownloadOperation : NSOperation | |
{ | |
NSURLRequest *request; | |
NSURLConnection *connection; | |
NSMutableData *receivedData; | |
} | |
@property(readonly) BOOL isExecuting; | |
@property(readonly) BOOL isFinished; | |
@property(readonly) NSData *receivedData; | |
- (id) initWithRequest: (NSURLRequest*) rq; | |
@end |
This file contains hidden or 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
#import "DownloadOperation.h" | |
@interface DownloadOperation () | |
@property(assign) BOOL isExecuting; | |
@property(assign) BOOL isFinished; | |
@end | |
@implementation DownloadOperation | |
@synthesize isExecuting, isFinished, receivedData; | |
#pragma mark Initialization | |
- (id) initWithRequest: (NSURLRequest*) rq | |
{ | |
[super init]; | |
request = [rq retain]; | |
return self; | |
} | |
- (void) dealloc | |
{ | |
[request release]; | |
[super dealloc]; | |
} | |
#pragma mark NSOperation Stuff | |
- (void) start | |
{ | |
NSParameterAssert(request); | |
// Bail out early if cancelled. | |
if ([self isCancelled]) { | |
[self setIsFinished:YES]; | |
[self setIsExecuting:NO]; | |
return; | |
} | |
[self setIsExecuting:YES]; | |
[self setIsFinished:NO]; | |
receivedData = [[NSMutableData alloc] init]; | |
// Make sure the connection runs in the main run loop. | |
connection = [[NSURLConnection alloc] initWithRequest:request | |
delegate:self startImmediately:NO]; | |
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] | |
forMode:NSDefaultRunLoopMode]; | |
[connection start]; | |
} | |
- (BOOL) isConcurrent | |
{ | |
return YES; | |
} | |
#pragma mark NSURLConnection Callbacks | |
- (void) connection: (NSURLConnection*) cn didReceiveData: (NSData*) data | |
{ | |
// Not cancelled, receive data. | |
if (![self isCancelled]) { | |
[receivedData appendData:data]; | |
return; | |
} | |
// Cancelled, tear down connection. | |
[self setIsExecuting:NO]; | |
[self setIsFinished:YES]; | |
[connection cancel]; | |
[connection release]; | |
[receivedData release]; | |
} | |
- (void) connectionDidFinishLoading: (NSURLConnection*) cn | |
{ | |
[self setIsExecuting:NO]; | |
[self setIsFinished:YES]; | |
[receivedData release]; | |
[connection release]; | |
} | |
- (void) connection: (NSURLConnection*) cn didFailWithError: (NSError*) error | |
{ | |
[self setIsExecuting:NO]; | |
[self setIsFinished:YES]; | |
[connection release]; | |
[receivedData release]; | |
} | |
// http://stackoverflow.com/questions/3573236 | |
+ (BOOL) automaticallyNotifiesObserversForKey: (NSString*) key | |
{ | |
return YES; | |
} | |
@end |
Dear zoul,
Thanks for sharing this.
Is there any advantage to run NSURLConnection within a concurrent NSOperation? I suppose it is possible to have the same effect just creating a wrapper around the connection.
My supposition is that I could use queues in order to manage the number of running operations, dependencies among operations and so on.
I ask it since the connection is shunted on the main thread and, so, callbacks will be called on that thread. So, no threading mechanism is involved here.
Thank you for your attention.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hm. I'm not sure you really need to release the delegate. According to the NSURLConnection documentation:
Special Considerations
The connection retains delegate. It releases delegate when the connection finishes loading, fails, or is canceled.