Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions RequestQueue/RequestQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ RequestQueueMode;
@property (nonatomic, copy) RQAuthenticationChallengeHandler authenticationChallengeHandler;
@property (nonatomic, copy) NSSet *autoRetryErrorCodes;
@property (nonatomic, assign) BOOL autoRetry;
@property (nonatomic, assign) NSInteger uploadBytesTotal;
@property (nonatomic, assign) NSInteger uploadBytesDone;
@property (nonatomic, assign) NSInteger downloadBytesTotal;
@property (nonatomic, assign) NSInteger downloadBytesDone;

+ (RQOperation *)operationWithRequest:(NSURLRequest *)request;
- (RQOperation *)initWithRequest:(NSURLRequest *)request;
Expand All @@ -103,6 +107,7 @@ RequestQueueMode;
@property (nonatomic, strong, readonly) NSArray *requests;
@property (nonatomic, assign) RequestQueueMode queueMode;
@property (nonatomic, assign) BOOL allowDuplicateRequests;
@property (nonatomic, copy) void(^completionHandler)(BOOL success);

+ (RequestQueue *)mainQueue;

Expand All @@ -111,4 +116,9 @@ RequestQueueMode;
- (void)cancelRequest:(NSURLRequest *)request;
- (void)cancelAllRequests;

// Call this method before adding operations to this queue.
// Whenever an operation fails, an internal success flag becomes `NO`.
// This flag is then passed to the `completionHandler` block.
- (void)clearSuccessFlag;

@end
35 changes: 26 additions & 9 deletions RequestQueue/RequestQueue.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ @interface RQOperation () <NSURLConnectionDataDelegate>
@property (assign, getter = isExecuting) BOOL executing;
@property (assign, getter = isFinished) BOOL finished;
@property (assign, getter = isCancelled) BOOL cancelled;
@property (assign) BOOL success;

@end

Expand Down Expand Up @@ -117,7 +118,7 @@ - (void)cancel
}
}

- (void)finish
- (void)finish:(BOOL)success
{
@synchronized (self)
{
Expand All @@ -127,6 +128,7 @@ - (void)finish
[self willChangeValueForKey:@"isFinished"];
_executing = NO;
_finished = YES;
_success = success;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}
Expand Down Expand Up @@ -179,7 +181,7 @@ - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)err
}
else
{
[self finish];
[self finish:NO];
if (_completionHandler) _completionHandler(_responseReceived, _accumulatedData, error);
}
}
Expand All @@ -203,6 +205,8 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
self.uploadBytesTotal = totalBytesExpectedToWrite;
self.uploadBytesDone = totalBytesWritten;
if (_uploadProgressHandler)
{
float progress = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
Expand All @@ -217,18 +221,16 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
_accumulatedData = [[NSMutableData alloc] initWithCapacity:MAX(0, _responseReceived.expectedContentLength)];
}
[_accumulatedData appendData:data];
self.downloadBytesTotal = MAX(0, _responseReceived.expectedContentLength);
self.downloadBytesDone = [_accumulatedData length];
if (_downloadProgressHandler)
{
NSInteger bytesTransferred = [_accumulatedData length];
NSInteger totalBytes = MAX(0, _responseReceived.expectedContentLength);
_downloadProgressHandler((float)bytesTransferred / (float)totalBytes, bytesTransferred, totalBytes);
_downloadProgressHandler((float)self.downloadBytesDone / (float)self.downloadBytesTotal, self.downloadBytesDone, self.downloadBytesTotal);
}
}

- (void)connectionDidFinishLoading:(NSURLConnection *)_connection
{
[self finish];

NSError *error = nil;
if ([_responseReceived respondsToSelector:@selector(statusCode)])
{
Expand All @@ -243,7 +245,8 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)_connection
userInfo:infoDict];
}
}


[self finish:(error == nil)];
if (_completionHandler) _completionHandler(_responseReceived, _accumulatedData, error);
}

Expand All @@ -257,7 +260,9 @@ @interface RequestQueue () <NSURLConnectionDataDelegate>
@end


@implementation RequestQueue
@implementation RequestQueue {
BOOL _success;
}

@synthesize maxConcurrentRequestCount = _maxConcurrentRequestCount;
@synthesize suspended = _suspended;
Expand All @@ -283,6 +288,7 @@ - (id)init
_operations = [[NSMutableArray alloc] init];
_maxConcurrentRequestCount = 2;
_allowDuplicateRequests = NO;
[self clearSuccessFlag];
}
return self;
}
Expand Down Expand Up @@ -313,6 +319,10 @@ - (void)dequeueOperations
[(RQOperation *)[_operations objectAtIndex:i] start];
}
}

if ([_operations count] == 0 && self.completionHandler != nil) {
self.completionHandler(_success);
}
}

#pragma mark Public methods
Expand Down Expand Up @@ -394,11 +404,18 @@ - (void)cancelAllRequests
}
}

- (void)clearSuccessFlag {
_success = YES;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
RQOperation *operation = object;
if (!operation.executing)
{
if (!operation.success) {
_success = NO;
}
[operation removeObserver:self forKeyPath:@"isExecuting"];
[_operations removeObject:operation];
[self dequeueOperations];
Expand Down