Ben Copsey

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
... ... @@ -36,6 +36,7 @@
postData = [[NSMutableDictionary alloc] init];
}
[postData setValue:value forKey:key];
[self setRequestMethod:@"POST"];
}
- (void)setFile:(NSString *)filePath forKey:(NSString *)key
... ... @@ -44,32 +45,22 @@
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 @@
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 @@
}
[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
... ...
... ... @@ -12,6 +12,7 @@
@implementation ASIFormDataRequestTests
- (void)testPostWithFileUpload
{
... ... @@ -21,13 +22,11 @@
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");
... ...
... ... @@ -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
... ...
... ... @@ -51,12 +51,17 @@ static NSLock *progressLock;
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 @@ static NSLock *progressLock;
CFRelease(request);
}
[self cancelLoad];
[mainRequest release];
[postBody release];
[requestCredentials release];
[error release];
... ... @@ -116,7 +122,18 @@ static NSLock *progressLock;
-(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,7 +214,11 @@ static NSLock *progressLock;
[self addRequestHeader:@"Cookie" value:cookieHeader];
}
}
if (!haveBuiltPostBody) {
[self buildPostBody];
}
// Add custom headers
NSString *header;
... ... @@ -205,13 +226,15 @@ static NSLock *progressLock;
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 @@ static NSLock *progressLock;
}
lastBytesSent = 0;
contentLength = 0;
if (!useCachedContentLength) {
contentLength = 0;
}
[self setResponseHeaders:nil];
[self setReceivedData:[[[NSMutableData alloc] init] autorelease]];
... ... @@ -267,7 +292,6 @@ static NSLock *progressLock;
[self failWithProblem:@"Unable to start http connection"];
return;
}
if (uploadProgressDelegate) {
[self performSelectorOnMainThread:@selector(resetUploadProgress:) withObject:[NSNumber numberWithDouble:postLength] waitUntilDone:YES];
... ... @@ -340,9 +364,14 @@ static NSLock *progressLock;
- (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 @@ static NSLock *progressLock;
//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 @@ static NSLock *progressLock;
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 @@ static NSLock *progressLock;
//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 @@ static NSLock *progressLock;
- (void)handleNetworkEvent:(CFStreamEventType)type
{
// Dispatch the stream events.
switch (type) {
case kCFStreamEventHasBytesAvailable:
... ... @@ -898,9 +945,18 @@ static NSLock *progressLock;
- (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 @@ static NSLock *progressLock;
}
@synthesize username;
@synthesize password;
@synthesize domain;
... ... @@ -1047,4 +1100,8 @@ static NSLock *progressLock;
@synthesize requestMethod;
@synthesize postBody;
@synthesize contentLength;
@synthesize postLength;
@synthesize useCachedContentLength;
@synthesize mainRequest;
@synthesize showAccurateProgress;
@end
... ...
... ... @@ -117,7 +117,7 @@
- (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 @@
}
@end
... ...
... ... @@ -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
... ...
... ... @@ -31,17 +31,37 @@
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 @@
[invocation setSelector:selector];
[invocation setArgument:&max atIndex:2];
[invocation invokeWithTarget:uploadProgressDelegate];
}
}
... ... @@ -79,48 +98,96 @@
}
}
- (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 @@
return;
}
downloadProgressBytes += bytes;
//NSLog(@"%hu/%hu",downloadProgressBytes,downloadProgressTotalBytes);
double progress = (downloadProgressBytes*1.0)/(downloadProgressTotalBytes*1.0);
[ASIHTTPRequest setProgress:progress forProgressIndicator:downloadProgressDelegate];
}
... ... @@ -173,6 +240,7 @@
}
@synthesize uploadProgressDelegate;
@synthesize downloadProgressDelegate;
@synthesize requestDidFinishSelector;
... ... @@ -180,4 +248,6 @@
@synthesize queueDidFinishSelector;
@synthesize shouldCancelAllRequestsOnFailure;
@synthesize delegate;
@synthesize showAccurateProgress;
@end
... ...
... ... @@ -21,21 +21,23 @@
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 @@
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 @@
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 @@
url = [[[NSURL alloc] initWithString:@""] autorelease];
requestThatShouldFail = [[ASIHTTPRequest alloc] initWithURL:url];
[networkQueue addOperation:requestThatShouldFail];
[networkQueue go];
NSDate* endDate = [NSDate distantFuture];
while (!complete) {
... ...
... ... @@ -16,6 +16,8 @@
IBOutlet NSWindow *window;
IBOutlet NSWindow *loginWindow;
IBOutlet NSButton *showAccurateProgress;
IBOutlet NSTextField *host;
IBOutlet NSTextField *realm;
IBOutlet NSTextField *username;
... ...
... ... @@ -43,6 +43,7 @@
- (IBAction)URLFetchWithProgress:(id)sender
{
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setDelegate:self];
[networkQueue setRequestDidFinishSelector:@selector(URLFetchWithProgressComplete:)];
... ... @@ -50,6 +51,7 @@
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 @@
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setRequestDidFinishSelector:@selector(imageFetchComplete:)];
[networkQueue setDelegate:self];
[networkQueue setShowAccurateProgress:([showAccurateProgress state] == NSOnState)];
ASIHTTPRequest *request;
... ... @@ -85,6 +88,9 @@
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 @@
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 @@
[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];
}
... ...
... ... @@ -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>
... ...
... ... @@ -38,6 +38,8 @@
request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/sharedspace20.png"]] autorelease];
[networkQueue addOperation:request];
[networkQueue go];
}
... ...