Browse files

Big changes to progress tracking:

Added ability to use non-accurate progress for speed
Request HEAD for GET requests when in accurate mode
Calculate postLength outside of main
Bug fixes
  • Loading branch information...
1 parent 77aa3f3 commit 83dd4d93d8800a9dd58ea9fb3c5a77a74b36505a @pokeb committed Nov 10, 2008
View
35 ASIFormDataRequest.m
@@ -36,6 +36,7 @@ - (void)setPostValue:(id)value forKey:(NSString *)key
postData = [[NSMutableDictionary alloc] init];
}
[postData setValue:value forKey:key];
+ [self setRequestMethod:@"POST"];
}
- (void)setFile:(NSString *)filePath forKey:(NSString *)key
@@ -44,32 +45,22 @@ - (void)setFile:(NSString *)filePath forKey:(NSString *)key
fileData = [[NSMutableDictionary alloc] init];
}
[fileData setValue:filePath forKey:key];
+ [self setRequestMethod:@"POST"];
}
-
-#pragma mark request logic
-
-// Create the request
-- (void)main
+- (void)buildPostBody
{
-
- // If the user didn't specify post data, we will let ASIHTTPRequest use the value of body
- if ([postData count] == 0 && [fileData count] == 0) {
- [super main];
- return;
- }
-
NSMutableData *body = [[[NSMutableData alloc] init] autorelease];
// Set your own boundary string only if really obsessive. We don't bother to check if post data contains the boundary, since it's pretty unlikely that it does.
NSString *stringBoundary = @"0xKhTmLbOuNdArY";
- if ([fileData count] > 0) {
+ //if ([fileData count] > 0) {
// We need to use multipart/form-data when using file upload
- [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary]];
- }
+ [self addRequestHeader:@"Content-Type" value:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary]];
+ //}
+
-
[body appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
@@ -95,7 +86,9 @@ - (void)main
NSString *filePath = [fileData objectForKey:key];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",key,[filePath lastPathComponent]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:contentTypeHeader];
- [body appendData:[NSData dataWithContentsOfMappedFile:filePath]];
+ //[body appendData: [NSData dataWithContentsOfFile:filePath options:NSUncachedRead error:NULL]];
+ //[body appendData:[NSData dataWithContentsOfMappedFile:filePath]];
+ [body appendData:[NSData dataWithContentsOfFile:filePath]];
i++;
// Only add the boundary if this is not the last item in the post body
if (i != [fileData count]) {
@@ -104,14 +97,14 @@ - (void)main
}
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
-
- [self setPostBody:body];
- //Now we've created our post data, construct the request
- [super main];
+ [self setPostBody:body];
+
+ [super buildPostBody];
}
+
@end
View
7 ASIFormDataRequestTests.m
@@ -12,6 +12,7 @@
@implementation ASIFormDataRequestTests
+
- (void)testPostWithFileUpload
{
@@ -21,13 +22,11 @@ - (void)testPostWithFileUpload
NSString *path = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"bigfile"];
[data writeToFile:path atomically:NO];
- ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/asi-http-request/tests/post"]] autorelease];
- [request setDelegate:self];
-
+ ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://asi/asi-http-request/tests/post"]] autorelease];
[request setPostValue:@"foo" forKey:@"post_var"];
[request setFile:path forKey:@"file"];
- [request setUploadProgressDelegate:self];
[request start];
+
BOOL success = ([[request dataString] isEqualToString:[NSString stringWithFormat:@"post_var: %@\r\nfile_name: %@\r\nfile_size: %hu",@"foo",@"bigfile",size]]);
STAssertTrue(success,@"Failed to upload the correct data");
View
23 ASIHTTPRequest.h
@@ -121,9 +121,27 @@
//Used for recording when something last happened during the request, we will compare this value with the current date to time out requests when appropriate
NSDate *lastActivityTime;
+ // Number of seconds to wait before timing out - default is 10
NSTimeInterval timeOutSeconds;
+ // Autorelease pool for the main loop, since it's highly likely that this operation will run in a thread
NSAutoreleasePool *pool;
+
+ // Will be YES when a HEAD request will handle the content-length before this request starts
+ BOOL useCachedContentLength;
+
+ // Used by HEAD requests when showAccurateProgress is YES to preset the content-length for this request
+ ASIHTTPRequest *mainRequest;
+
+ // When NO, this request will only update the progress indicator when it completes
+ // When YES, this request will update the progress indicator according to how much data it has recieved so far
+ // The default for requests is YES
+ // Also see the comments in ASINetworkQueue.h
+ BOOL showAccurateProgress;
+
+ BOOL updatedProgress;
+
+ BOOL haveBuiltPostBody;
}
#pragma mark init / dealloc
@@ -136,6 +154,7 @@
//Add a custom header to the request
- (void)addRequestHeader:(NSString *)header value:(NSString *)value;
+- (void)buildPostBody;
#pragma mark get information about this request
@@ -262,4 +281,8 @@
@property (retain) NSString *requestMethod;
@property (retain,setter=setPostBody:) NSData *postBody;
@property (assign) unsigned int contentLength;
+@property (assign) unsigned int postLength;
+@property (assign) BOOL useCachedContentLength;
+@property (retain) ASIHTTPRequest *mainRequest;
+@property (assign) BOOL showAccurateProgress;
@end
View
103 ASIHTTPRequest.m
@@ -51,12 +51,17 @@ - (id)initWithURL:(NSURL *)newURL
self = [super init];
[self setRequestMethod:@"GET"];
lastBytesSent = 0;
+ showAccurateProgress = YES;
+ useCachedContentLength = NO;
+ updatedProgress = NO;
+ mainRequest = nil;
username = nil;
password = nil;
requestHeaders = nil;
authenticationRealm = nil;
outputStream = nil;
requestAuthentication = NULL;
+ haveBuiltPostBody = NO;
//credentials = NULL;
request = NULL;
responseHeaders = nil;
@@ -81,6 +86,7 @@ - (void)dealloc
CFRelease(request);
}
[self cancelLoad];
+ [mainRequest release];
[postBody release];
[requestCredentials release];
[error release];
@@ -116,7 +122,18 @@ - (void)addRequestHeader:(NSString *)header value:(NSString *)value
-(void)setPostBody:(NSData *)body
{
postBody = [body retain];
- [self setRequestMethod:@"POST"];
+ postLength = [postBody length];
+ if (postBody && postLength > 0 && ![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) {
+ [self setRequestMethod:@"POST"];
+ }
+}
+
+// Subclasses should override this method if they need to create POST content for this request
+// This function will be called either just before a request starts, or when postLength is needed, whichever comes first
+// postLength must be set by the time this function is complete - calling setPostBody: will do this for you
+- (void)buildPostBody
+{
+ haveBuiltPostBody = YES;
}
#pragma mark get information about this request
@@ -197,21 +214,27 @@ - (void)main
[self addRequestHeader:@"Cookie" value:cookieHeader];
}
}
-
+
+
+ if (!haveBuiltPostBody) {
+ [self buildPostBody];
+ }
// Add custom headers
NSString *header;
for (header in requestHeaders) {
CFHTTPMessageSetHeaderFieldValue(request, (CFStringRef)header, (CFStringRef)[requestHeaders objectForKey:header]);
}
+
+
+
// If this is a post request and we have data to send, add it to the request
if ([self postBody]) {
CFHTTPMessageSetBody(request, (CFDataRef)postBody);
- postLength = [postBody length];
}
-
+
[self loadRequest];
}
@@ -235,7 +258,9 @@ - (void)loadRequest
}
lastBytesSent = 0;
- contentLength = 0;
+ if (!useCachedContentLength) {
+ contentLength = 0;
+ }
[self setResponseHeaders:nil];
[self setReceivedData:[[[NSMutableData alloc] init] autorelease]];
@@ -267,7 +292,6 @@ - (void)loadRequest
[self failWithProblem:@"Unable to start http connection"];
return;
}
-
if (uploadProgressDelegate) {
[self performSelectorOnMainThread:@selector(resetUploadProgress:) withObject:[NSNumber numberWithDouble:postLength] waitUntilDone:YES];
@@ -340,9 +364,14 @@ - (void)cancelLoad
- (void)updateProgressIndicators
{
-
- [self updateUploadProgress];
- [self updateDownloadProgress];
+ //Only update progress if this isn't a HEAD request used to preset the content-length
+ if (!mainRequest) {
+
+ if (showAccurateProgress || (complete && !updatedProgress)) {
+ [self updateUploadProgress];
+ [self updateDownloadProgress];
+ }
+ }
}
@@ -421,7 +450,13 @@ - (void)updateUploadProgress
//We're using a progress queue or compatible controller to handle progress
if ([uploadProgressDelegate respondsToSelector:@selector(incrementUploadProgressBy:)]) {
- int value = byteCount-lastBytesSent;
+ int value = 0;
+ if (showAccurateProgress) {
+ value = byteCount-lastBytesSent;
+ } else {
+ value = 1;
+ updatedProgress = YES;
+ }
SEL selector = @selector(incrementUploadProgressBy:);
NSMethodSignature *signature = nil;
signature = [[uploadProgressDelegate class] instanceMethodSignatureForSelector:selector];
@@ -485,7 +520,14 @@ - (void)updateDownloadProgress
NSAutoreleasePool *thePool = [[NSAutoreleasePool alloc] init];
- int value = totalBytesRead-lastBytesRead;
+ int value = 0;
+ if (showAccurateProgress) {
+ value = totalBytesRead-lastBytesRead;
+ } else {
+ value = 1;
+ updatedProgress = YES;
+ }
+
SEL selector = @selector(incrementDownloadProgressBy:);
NSMethodSignature *signature = [[downloadProgressDelegate class] instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
@@ -614,12 +656,18 @@ - (BOOL)readResponseHeadersReturningAuthenticationFailure
//We won't reset the download progress delegate if we got an authentication challenge
if (!isAuthenticationChallenge) {
- //See if we got a Content-length header
- NSString *cLength = [responseHeaders valueForKey:@"Content-Length"];
- if (cLength) {
- contentLength = CFStringGetDoubleValue((CFStringRef)cLength);
- if (downloadProgressDelegate) {
- [self performSelectorOnMainThread:@selector(resetDownloadProgress:) withObject:[NSNumber numberWithDouble:contentLength] waitUntilDone:YES];
+ //Only check the content length if we haven't already got one (may have been set by an ASINetworkQueue using a previous HEAD request)
+ if (!useCachedContentLength) {
+ //See if we got a Content-length header
+ NSString *cLength = [responseHeaders valueForKey:@"Content-Length"];
+ if (cLength) {
+ contentLength = CFStringGetDoubleValue((CFStringRef)cLength);
+ if (mainRequest) {
+ [mainRequest setContentLength:contentLength];
+ }
+ if (downloadProgressDelegate && showAccurateProgress) {
+ [self performSelectorOnMainThread:@selector(resetDownloadProgress:) withObject:[NSNumber numberWithDouble:contentLength] waitUntilDone:YES];
+ }
}
}
@@ -836,7 +884,6 @@ - (NSError *)authenticationError
- (void)handleNetworkEvent:(CFStreamEventType)type
{
-
// Dispatch the stream events.
switch (type) {
case kCFStreamEventHasBytesAvailable:
@@ -898,9 +945,18 @@ - (void)handleBytesAvailable
- (void)handleStreamComplete
{
+
+ //Try to read the headers (if this is a HEAD request handleBytesAvailable available may not be called)
+ if (!responseHeaders) {
+ if ([self readResponseHeadersReturningAuthenticationFailure]) {
+ [self attemptToApplyCredentialsAndResume];
+ return;
+ }
+ }
+
+
complete = YES;
- [self updateUploadProgress];
- [self updateDownloadProgress];
+ [self updateProgressIndicators];
if (readStream) {
CFReadStreamClose(readStream);
CFReadStreamSetClient(readStream, kCFStreamEventNone, NULL, NULL);
@@ -1017,9 +1073,6 @@ + (void)clearSession
}
-
-
-
@synthesize username;
@synthesize password;
@synthesize domain;
@@ -1047,4 +1100,8 @@ + (void)clearSession
@synthesize requestMethod;
@synthesize postBody;
@synthesize contentLength;
+@synthesize postLength;
+@synthesize useCachedContentLength;
+@synthesize mainRequest;
+@synthesize showAccurateProgress;
@end
View
3 ASIHTTPRequestTests.m
@@ -117,7 +117,7 @@ - (void)testDownloadProgress
- (void)testUploadProgress
{
progress = 0;
- ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]] autorelease];
+ ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://asi/ignore"]] autorelease];
[request setPostBody:[NSMutableData dataWithLength:1024*32]];
[request setUploadProgressDelegate:self];
[request start];
@@ -357,4 +357,5 @@ - (void)testDigestAuthentication
}
+
@end
View
27 ASINetworkQueue.h
@@ -26,27 +26,39 @@
id uploadProgressDelegate;
// Total amount uploaded so far for all requests in this queue
- int uploadProgressBytes;
+ unsigned int uploadProgressBytes;
// Total amount to be uploaded for all requests in this queue - requests add to this figure as they work out how much data they have to transmit
- int uploadProgressTotalBytes;
+ unsigned int uploadProgressTotalBytes;
// Download progress indicator, probably an NSProgressIndicator or UIProgressView
id downloadProgressDelegate;
// Total amount downloaded so far for all requests in this queue
- int downloadProgressBytes;
+ unsigned int downloadProgressBytes;
// Total amount to be downloaded for all requests in this queue - requests add to this figure as they receive Content-Length headers
- int downloadProgressTotalBytes;
+ unsigned int downloadProgressTotalBytes;
// When YES, the queue will cancel all requests when a request fails. Default is YES
BOOL shouldCancelAllRequestsOnFailure;
+ //Number of real requests (excludes HEAD requests created to manage showAccurateProgress)
int requestsCount;
- int requestsCompleteCount;
+
+ // When NO, this request will only update the progress indicator when it completes
+ // When YES, this request will update the progress indicator according to how much data it has recieved so far
+ // When YES, the queue will first perform HEAD requests for all GET requests in the queue, so it can calculate the total download size before it starts
+ // NO means better performance, because it skips this step for GET requests, and it won't waste time updating the progress indicator until a request completes
+ // Set to YES if the size of a requests in the queue varies greatly for much more accurate results
+ // Default for requests in the queue is NO
+ BOOL showAccurateProgress;
+
+
}
+// Used internally to manage HEAD requests when showAccurateProgress is YES, do not use!
+- (void)addHEADOperation:(NSOperation *)operation;
// Called at the start of a request to add on the size of this upload to the total
- (void)incrementUploadSizeBy:(int)bytes;
@@ -60,6 +72,10 @@
// Called during a request when data is received to increment the progress indicator
- (void)incrementDownloadProgressBy:(int)bytes;
+// All ASINetworkQueues are paused when created so that total size can be calculated before the queue starts
+// This method will start the queue
+- (void)go;
+
@property (assign,setter=setUploadProgressDelegate:) id uploadProgressDelegate;
@property (assign,setter=setDownloadProgressDelegate:) id downloadProgressDelegate;
@@ -68,4 +84,5 @@
@property (assign) SEL queueDidFinishSelector;
@property (assign) BOOL shouldCancelAllRequestsOnFailure;
@property (assign) id delegate;
+@property (assign) BOOL showAccurateProgress;
@end
View
102 ASINetworkQueue.m
@@ -31,17 +31,37 @@ - (id)init
downloadProgressTotalBytes = 0;
requestsCount = 0;
- requestsCompleteCount = 0;
+
+ showAccurateProgress = NO;
+
+ [self setSuspended:YES];
return self;
}
+- (void)go
+{
+ if (!showAccurateProgress) {
+ if (downloadProgressDelegate) {
+ [self incrementDownloadSizeBy:requestsCount];
+ }
+ if (uploadProgressDelegate) {
+ [self incrementUploadSizeBy:requestsCount];
+ }
+ }
+ [self setSuspended:NO];
+}
+
- (void)cancelAllOperations
{
+ requestsCount = 0;
uploadProgressBytes = 0;
uploadProgressTotalBytes = 0;
downloadProgressBytes = 0;
- downloadProgressTotalBytes = 0;
+ downloadProgressTotalBytes = 0;
+ [self setUploadProgressDelegate:nil];
+ [self setDownloadProgressDelegate:nil];
+ [self setDelegate:nil];
[super cancelAllOperations];
}
@@ -58,7 +78,6 @@ - (void)setUploadProgressDelegate:(id)newDelegate
[invocation setSelector:selector];
[invocation setArgument:&max atIndex:2];
[invocation invokeWithTarget:uploadProgressDelegate];
-
}
}
@@ -79,48 +98,96 @@ - (void)setDownloadProgressDelegate:(id)newDelegate
}
}
+- (void)addHEADOperation:(NSOperation *)operation
+{
+ if ([operation isKindOfClass:[ASIHTTPRequest class]]) {
+
+ ASIHTTPRequest *request = (ASIHTTPRequest *)operation;
+ [request setShowAccurateProgress:YES];
+ if (uploadProgressDelegate) {
+ [request setUploadProgressDelegate:self];
+ } else {
+ [request setUploadProgressDelegate:NULL];
+ }
+ if (downloadProgressDelegate) {
+ [request setDownloadProgressDelegate:self];
+ } else {
+ [request setDownloadProgressDelegate:NULL];
+ }
+ [request setDelegate:self];
+ [super addOperation:request];
+ }
+}
+
// Only add ASIHTTPRequests to this queue!!
- (void)addOperation:(NSOperation *)operation
{
if ([operation isKindOfClass:[ASIHTTPRequest class]]) {
+
requestsCount++;
+
+ ASIHTTPRequest *request = (ASIHTTPRequest *)operation;
+
+ if (showAccurateProgress) {
+
+ //If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length
+ if ([[request requestMethod] isEqualToString:@"GET"]) {
+ ASIHTTPRequest *HEADRequest = [[[ASIHTTPRequest alloc] initWithURL:[request url]] autorelease];
+ [HEADRequest setRequestMethod:@"HEAD"];
+ [HEADRequest setQueuePriority:10];
+ [HEADRequest setMainRequest:request];
+ [self addHEADOperation:HEADRequest];
+
+ [request setUseCachedContentLength:YES];
+ [request addDependency:HEADRequest];
+
+ //If we want to track uploading for this request accurately, we need to add the size of the post content to the total
+ } else if (uploadProgressDelegate) {
+ [request buildPostBody];
+ uploadProgressTotalBytes += [request postLength];
+ }
+ }
+ [request setShowAccurateProgress:showAccurateProgress];
+
if (uploadProgressDelegate) {
- [(ASIHTTPRequest *)operation setUploadProgressDelegate:self];
+ [request setUploadProgressDelegate:self];
} else {
- [(ASIHTTPRequest *)operation setUploadProgressDelegate:NULL];
+ [request setUploadProgressDelegate:NULL];
}
if (downloadProgressDelegate) {
- [(ASIHTTPRequest *)operation setDownloadProgressDelegate:self];
+ [request setDownloadProgressDelegate:self];
} else {
- [(ASIHTTPRequest *)operation setDownloadProgressDelegate:NULL];
+ [request setDownloadProgressDelegate:NULL];
}
- [(ASIHTTPRequest *)operation setDelegate:self];
- [(ASIHTTPRequest *)operation setDidFailSelector:@selector(requestDidFail:)];
- [(ASIHTTPRequest *)operation setDidFinishSelector:@selector(requestDidFinish:)];
- [super addOperation:operation];
+ [request setDelegate:self];
+ [request setDidFailSelector:@selector(requestDidFail:)];
+ [request setDidFinishSelector:@selector(requestDidFinish:)];
+ [super addOperation:request];
}
}
- (void)requestDidFail:(ASIHTTPRequest *)request
{
+ requestsCount--;
if (requestDidFailSelector) {
[delegate performSelector:requestDidFailSelector withObject:request];
}
if (shouldCancelAllRequestsOnFailure) {
[self cancelAllOperations];
}
- requestsCompleteCount++;
}
- (void)requestDidFinish:(ASIHTTPRequest *)request
{
- requestsCompleteCount++;
+ requestsCount--;
if (requestDidFinishSelector) {
[delegate performSelector:requestDidFinishSelector withObject:request];
}
- if (queueDidFinishSelector && requestsCompleteCount == requestsCount) {
- [delegate performSelector:queueDidFinishSelector withObject:self];
+ if (requestsCount == 0) {
+ if (queueDidFinishSelector) {
+ [delegate performSelector:queueDidFinishSelector withObject:self];
+ }
}
}
@@ -159,7 +226,7 @@ - (void)incrementDownloadProgressBy:(int)bytes
return;
}
downloadProgressBytes += bytes;
-
+ //NSLog(@"%hu/%hu",downloadProgressBytes,downloadProgressTotalBytes);
double progress = (downloadProgressBytes*1.0)/(downloadProgressTotalBytes*1.0);
[ASIHTTPRequest setProgress:progress forProgressIndicator:downloadProgressDelegate];
}
@@ -173,11 +240,14 @@ - (void)authorizationNeededForRequest:(ASIHTTPRequest *)request
}
+
@synthesize uploadProgressDelegate;
@synthesize downloadProgressDelegate;
@synthesize requestDidFinishSelector;
@synthesize requestDidFailSelector;
@synthesize queueDidFinishSelector;
@synthesize shouldCancelAllRequestsOnFailure;
@synthesize delegate;
+@synthesize showAccurateProgress;
+
@end
View
45 ASINetworkQueueTests.m
@@ -21,21 +21,23 @@ - (void)testProgress
networkQueue = [[ASINetworkQueue alloc] init];
[networkQueue setDownloadProgressDelegate:self];
[networkQueue setDelegate:self];
- [networkQueue setRequestDidFinishSelector:@selector(queueFinished:)];
+ [networkQueue setShowAccurateProgress:NO];
+ [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)];
NSURL *url;
- url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/first"] autorelease];
+ url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
ASIHTTPRequest *request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request1];
- url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/second"] autorelease];
+ url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/trailsnetwork.png"] autorelease];
ASIHTTPRequest *request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request2];
- url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/third"] autorelease];
+ url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/sharedspace20.png"] autorelease];
ASIHTTPRequest *request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request3];
+ [networkQueue go];
NSDate* endDate = [NSDate distantFuture];
while (!complete) {
@@ -45,9 +47,39 @@ - (void)testProgress
BOOL success = (progress == 1.0);
STAssertTrue(success,@"Failed to increment progress properly");
+ //Now test again with accurate progress
+
+ [networkQueue cancelAllOperations];
+ [networkQueue setShowAccurateProgress:YES];
+
+ url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
+ request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
+ [networkQueue addOperation:request1];
+
+ url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/trailsnetwork.png"] autorelease];
+ request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
+ [networkQueue addOperation:request2];
+
+ url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/sharedspace20.png"] autorelease];
+ request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
+ [networkQueue addOperation:request3];
+
+ [networkQueue go];
+
+ endDate = [NSDate distantFuture];
+ while (!complete) {
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate];
+ }
+
+ success = (progress == 1.0);
+ STAssertTrue(success,@"Failed to increment progress properly");
+
+
[networkQueue release];
+
+
}
- (void)setProgress:(float)newProgress
@@ -86,7 +118,8 @@ - (void)testFailure
url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/asi-http-request/tests/broken"] autorelease];
ASIHTTPRequest *request5 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request5];
-
+
+ [networkQueue go];
NSDate* endDate = [NSDate distantFuture];
while (!complete) {
@@ -154,6 +187,8 @@ - (void)testFailureCancelsOtherRequests
url = [[[NSURL alloc] initWithString:@""] autorelease];
requestThatShouldFail = [[ASIHTTPRequest alloc] initWithURL:url];
[networkQueue addOperation:requestThatShouldFail];
+
+ [networkQueue go];
NSDate* endDate = [NSDate distantFuture];
while (!complete) {
View
2 AppDelegate.h
@@ -16,6 +16,8 @@
IBOutlet NSWindow *window;
IBOutlet NSWindow *loginWindow;
+ IBOutlet NSButton *showAccurateProgress;
+
IBOutlet NSTextField *host;
IBOutlet NSTextField *realm;
IBOutlet NSTextField *username;
View
20 AppDelegate.m
@@ -43,13 +43,15 @@ - (IBAction)simpleURLFetch:(id)sender
- (IBAction)URLFetchWithProgress:(id)sender
{
[networkQueue cancelAllOperations];
+ [networkQueue setShowAccurateProgress:YES];
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setDelegate:self];
[networkQueue setRequestDidFinishSelector:@selector(URLFetchWithProgressComplete:)];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://trails-network.net/Downloads/MemexTrails_1.0b1.zip"]] autorelease];
[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"MemexTrails_1.0b1.zip"]];
[networkQueue addOperation:request];
+ [networkQueue go];
}
- (void)URLFetchWithProgressComplete:(ASIHTTPRequest *)request
@@ -71,6 +73,7 @@ - (IBAction)fetchThreeImages:(id)sender
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setRequestDidFinishSelector:@selector(imageFetchComplete:)];
[networkQueue setDelegate:self];
+ [networkQueue setShowAccurateProgress:([showAccurateProgress state] == NSOnState)];
ASIHTTPRequest *request;
@@ -85,6 +88,9 @@ - (IBAction)fetchThreeImages:(id)sender
request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/sharedspace20.png"]] autorelease];
[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"3.png"]];
[networkQueue addOperation:request];
+
+
+ [networkQueue go];
}
@@ -118,7 +124,7 @@ - (IBAction)fetchTopSecretInformation:(id)sender
request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/top_secret/"]] autorelease];
[request setUseKeychainPersistance:[keychainCheckbox state]];
[networkQueue addOperation:request];
-
+ [networkQueue go];
}
@@ -166,19 +172,19 @@ - (IBAction)postWithProgress:(id)sender
[data writeToFile:path atomically:NO];
[networkQueue cancelAllOperations];
- [progressIndicator setDoubleValue:0];
+ [networkQueue setShowAccurateProgress:YES];
+ [networkQueue setUploadProgressDelegate:progressIndicator];
+ [networkQueue setDelegate:self];
+
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]] autorelease];
- [request setDelegate:self];
-
[request setPostValue:@"test" forKey:@"value1"];
[request setPostValue:@"test" forKey:@"value2"];
[request setPostValue:@"test" forKey:@"value3"];
-
[request setFile:path forKey:@"file"];
- [networkQueue setUploadProgressDelegate:progressIndicator];
+
[networkQueue addOperation:request];
-
+ [networkQueue go];
}
View
77 English.lproj/MainMenu.xib
@@ -8,6 +8,7 @@
<string key="IBDocument.HIToolboxVersion">352.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="440"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -771,7 +772,6 @@
<object class="NSPSMatrix" key="NSDrawMatrix"/>
<string key="NSFrame">{{11, 16}, {151, 20}}</string>
<reference key="NSSuperview" ref="439893737"/>
- <reference key="NSWindow"/>
<int key="NSpiFlags">16392</int>
<double key="NSMaxValue">1.000000e+00</double>
</object>
@@ -780,7 +780,6 @@
<int key="NSvFlags">12</int>
<string key="NSFrame">{{6, 34}, {461, 289}}</string>
<reference key="NSSuperview" ref="439893737"/>
- <reference key="NSWindow"/>
<object class="NSMutableArray" key="NSTabViewItems">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTabViewItem" id="601615678">
@@ -1077,7 +1076,6 @@ cmVhZC4</string>
</object>
<string key="NSFrame">{{14, 163}, {139, 72}}</string>
<reference key="NSSuperview" ref="624078948"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="650701610">
<int key="NSCellFlags">130560</int>
@@ -1106,7 +1104,6 @@ cmVhZC4</string>
</object>
<string key="NSFrame">{{14, 84}, {139, 72}}</string>
<reference key="NSSuperview" ref="624078948"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="737332382">
<int key="NSCellFlags">130560</int>
@@ -1135,7 +1132,6 @@ cmVhZC4</string>
</object>
<string key="NSFrame">{{14, 4}, {139, 72}}</string>
<reference key="NSSuperview" ref="624078948"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="543138502">
<int key="NSCellFlags">130560</int>
@@ -1152,7 +1148,6 @@ cmVhZC4</string>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{156, 138}, {62, 32}}</string>
<reference key="NSSuperview" ref="624078948"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="11946473">
<int key="NSCellFlags">67239424</int>
@@ -1173,7 +1168,6 @@ cmVhZC4</string>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{159, 181}, {268, 51}}</string>
<reference key="NSSuperview" ref="624078948"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="118640000">
<int key="NSCellFlags">67239424</int>
@@ -1185,10 +1179,36 @@ cmVhZC4</string>
<reference key="NSTextColor" ref="981560827"/>
</object>
</object>
+ <object class="NSButton" id="986741348">
+ <reference key="NSNextResponder" ref="624078948"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{160, 110}, {172, 18}}</string>
+ <reference key="NSSuperview" ref="624078948"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="588048761">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Show accurate progress</string>
+ <reference key="NSSupport" ref="584670792"/>
+ <reference key="NSControlView" ref="986741348"/>
+ <int key="NSButtonFlags">1211912703</int>
+ <int key="NSButtonFlags2">130</int>
+ <object class="NSCustomResource" key="NSNormalImage" id="385619933">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSSwitch</string>
+ </object>
+ <object class="NSButtonImageSource" key="NSAlternateImage" id="938042219">
+ <string key="NSImageName">NSSwitch</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
</object>
<string key="NSFrame">{{10, 33}, {441, 243}}</string>
<reference key="NSSuperview" ref="495298985"/>
- <reference key="NSWindow"/>
</object>
<string key="NSLabel">Queue</string>
<reference key="NSColor" ref="482475293"/>
@@ -1253,13 +1273,8 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<reference key="NSControlView" ref="448108793"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
- <object class="NSCustomResource" key="NSNormalImage">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">NSSwitch</string>
- </object>
- <object class="NSButtonImageSource" key="NSAlternateImage">
- <string key="NSImageName">NSSwitch</string>
- </object>
+ <reference key="NSNormalImage" ref="385619933"/>
+ <reference key="NSAlternateImage" ref="938042219"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
@@ -1369,7 +1384,6 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
</object>
<string key="NSFrameSize">{480, 337}</string>
<reference key="NSSuperview"/>
- <reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
@@ -2062,6 +2076,14 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
</object>
<int key="connectionID">506</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">showAccurateProgress</string>
+ <reference key="source" ref="1010338297"/>
+ <reference key="destination" ref="986741348"/>
+ </object>
+ <int key="connectionID">515</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -2911,6 +2933,7 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<reference ref="448639965"/>
<reference ref="919017202"/>
<reference ref="1057121416"/>
+ <reference ref="986741348"/>
</object>
<reference key="parent" ref="725395930"/>
</object>
@@ -3239,6 +3262,20 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<reference key="object" ref="850742861"/>
<reference key="parent" ref="949500094"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">513</int>
+ <reference key="object" ref="986741348"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="588048761"/>
+ </object>
+ <reference key="parent" ref="624078948"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">514</int>
+ <reference key="object" ref="588048761"/>
+ <reference key="parent" ref="986741348"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -3461,6 +3498,8 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>503.IBPluginDependency</string>
<string>504.IBPluginDependency</string>
<string>505.IBPluginDependency</string>
+ <string>513.IBPluginDependency</string>
+ <string>514.IBPluginDependency</string>
<string>56.IBPluginDependency</string>
<string>56.ImportedFromIB2</string>
<string>57.IBPluginDependency</string>
@@ -3713,6 +3752,8 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
@@ -3766,7 +3807,7 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">506</int>
+ <int key="maxID">515</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -3810,6 +3851,7 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>password</string>
<string>progressIndicator</string>
<string>realm</string>
+ <string>showAccurateProgress</string>
<string>topSecretInfo</string>
<string>username</string>
<string>window</string>
@@ -3827,6 +3869,7 @@ c3N3b3JkLCBlbnRlciAndG9wc2VjcmV0JyBmb3IgYm90aC4</string>
<string>NSTextField</string>
<string>NSProgressIndicator</string>
<string>NSTextField</string>
+ <string>NSButton</string>
<string>NSTextField</string>
<string>NSTextField</string>
<string>NSWindow</string>
View
2 QueueViewController.m
@@ -38,6 +38,8 @@ - (IBAction)fetchThreeImages:(id)sender
request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/sharedspace20.png"]] autorelease];
[networkQueue addOperation:request];
+
+ [networkQueue go];
}

0 comments on commit 83dd4d9

Please sign in to comment.