You need to sign in or sign up before continuing.
Ben Copsey

ASIWebPageRequests now pass on most delegate calls to their parent's delegate

Improve iPad ASIWebPageRequest sample to show the resources being downloaded
... ... @@ -1636,7 +1636,7 @@ static NSOperationQueue *sharedQueue = nil;
{
if ([*target respondsToSelector:selector]) {
NSMethodSignature *signature = nil;
signature = [[*target class] instanceMethodSignatureForSelector:selector];
signature = [*target methodSignatureForSelector:selector];
NSInvocation *invocation = [[NSInvocation invocationWithMethodSignature:signature] retain];
[invocation setSelector:selector];
... ...
... ... @@ -43,7 +43,6 @@ static NSMutableArray *requestsUsingXMLParser = nil;
{
}
- (void)requestFinished
{
complete = NO;
... ... @@ -114,6 +113,9 @@ static NSMutableArray *requestsUsingXMLParser = nil;
[externalResourceRequest setParentRequest:self];
[externalResourceRequest setReplaceURLsWithDataURLs:[self replaceURLsWithDataURLs]];
[externalResourceRequest setShouldResetDownloadProgress:NO];
[externalResourceRequest setDelegate:self];
[externalResourceRequest setUploadProgressDelegate:self];
[externalResourceRequest setDownloadProgressDelegate:self];
if ([self downloadDestinationPath]) {
[externalResourceRequest setDownloadDestinationPath:[self cachePathForRequest:externalResourceRequest]];
}
... ... @@ -179,42 +181,18 @@ static NSMutableArray *requestsUsingXMLParser = nil;
[externalResourceRequest setParentRequest:self];
[externalResourceRequest setReplaceURLsWithDataURLs:[self replaceURLsWithDataURLs]];
[externalResourceRequest setShouldResetDownloadProgress:NO];
[externalResourceRequest setDelegate:self];
[externalResourceRequest setUploadProgressDelegate:self];
[externalResourceRequest setDownloadProgressDelegate:self];
if ([self downloadDestinationPath]) {
[externalResourceRequest setDownloadDestinationPath:[self cachePathForRequest:externalResourceRequest]];
}
[[self externalResourceQueue] addOperation:externalResourceRequest];
[externalResourceRequest setShowAccurateProgress:YES];
[self incrementDownloadSizeBy:1];
}
[[self externalResourceQueue] go];
}
- (void)updateDownloadProgress
{
if ([self parentRequest]) {
[[self parentRequest] updateDownloadProgress];
return;
}
[super updateDownloadProgress];
}
- (void)setContentLength:(unsigned long long)newContentLength
{
if ([self parentRequest]) {
[[self parentRequest] setContentLength:[[self parentRequest] contentLength]+newContentLength-contentLength];
}
[super setContentLength:newContentLength];
}
- (void)setTotalBytesRead:(unsigned long long)bytes
{
totalBytesRead = bytes;
if ([self parentRequest]) {
[[self parentRequest] setTotalBytesRead:[[self parentRequest] totalBytesRead]+totalBytesRead-lastBytesRead];
lastBytesRead = totalBytesRead;
return;
}
}
- (void)externalResourceFetchSucceeded:(ASIHTTPRequest *)externalResourceRequest
{
NSString *originalPath = [[externalResourceRequest userInfo] objectForKey:@"Path"];
... ... @@ -439,6 +417,52 @@ static NSMutableArray *requestsUsingXMLParser = nil;
xmlXPathFreeContext(xpathCtx);
}
- (BOOL)respondsToSelector:(SEL)selector
{
if ([self parentRequest]) {
return [[self parentRequest] respondsToSelector:selector];
}
//Ok, now check for selectors we want to pass on to the delegate
if (selector == @selector(requestStarted:) || selector == @selector(request:didReceiveResponseHeaders:) || selector == @selector(request:willRedirectToURL:) || selector == @selector(requestFinished:) || selector == @selector(requestFailed:) || selector == @selector(request:didReceiveData:) || selector == @selector(authenticationNeededForRequest:) || selector == @selector(proxyAuthenticationNeededForRequest:)) {
return [delegate respondsToSelector:selector];
} else if (selector == @selector(request:didReceiveBytes:) || selector == @selector(request:incrementDownloadSizeBy:)) {
return [downloadProgressDelegate respondsToSelector:selector];
} else if (selector == @selector(request:didSendBytes:) || selector == @selector(request:incrementUploadSizeBy:)) {
return [uploadProgressDelegate respondsToSelector:selector];
}
return [super respondsToSelector:selector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
if ([self parentRequest]) {
return [[self parentRequest] methodSignatureForSelector:selector];
}
if (selector == @selector(requestStarted:) || selector == @selector(request:didReceiveResponseHeaders:) || selector == @selector(request:willRedirectToURL:) || selector == @selector(requestFinished:) || selector == @selector(requestFailed:) || selector == @selector(request:didReceiveData:) || selector == @selector(authenticationNeededForRequest:) || selector == @selector(proxyAuthenticationNeededForRequest:)) {
return [(id)delegate methodSignatureForSelector:selector];
} else if (selector == @selector(request:didReceiveBytes:) || selector == @selector(request:incrementDownloadSizeBy:)) {
return [(id)downloadProgressDelegate methodSignatureForSelector:selector];
} else if (selector == @selector(request:didSendBytes:) || selector == @selector(request:incrementUploadSizeBy:)) {
return [(id)uploadProgressDelegate methodSignatureForSelector:selector];
}
return nil;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([self parentRequest]) {
return [[self parentRequest] forwardInvocation:anInvocation];
}
SEL selector = [anInvocation selector];
if (selector == @selector(requestStarted:) || selector == @selector(request:didReceiveResponseHeaders:) || selector == @selector(request:willRedirectToURL:) || selector == @selector(requestFinished:) || selector == @selector(requestFailed:) || selector == @selector(request:didReceiveData:) || selector == @selector(authenticationNeededForRequest:) || selector == @selector(proxyAuthenticationNeededForRequest:)) {
[anInvocation invokeWithTarget:delegate];
} else if (selector == @selector(request:didReceiveBytes:) || selector == @selector(request:incrementDownloadSizeBy:)) {
[anInvocation invokeWithTarget:downloadProgressDelegate];
} else if (selector == @selector(request:didSendBytes:) || selector == @selector(request:incrementUploadSizeBy:)) {
[anInvocation invokeWithTarget:uploadProgressDelegate];
}
}
+ (NSArray *)CSSURLsFromString:(NSString *)string
{
NSMutableArray *urls = [NSMutableArray array];
... ... @@ -496,6 +520,7 @@ static NSMutableArray *requestsUsingXMLParser = nil;
}
}
@synthesize externalResourceQueue;
@synthesize resourceList;
@synthesize parentRequest;
... ...
//
// RequestProgressCell.h
// iPhone
//
// Created by Ben Copsey on 03/10/2010.
// Copyright 2010 All-Seeing Interactive. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface RequestProgressCell : UITableViewCell {
UIProgressView *progressView;
}
+ (id)cell;
@property (assign, nonatomic) UIProgressView *progressView;
@end
... ...
//
// RequestProgressCell.m
// iPhone
//
// Created by Ben Copsey on 03/10/2010.
// Copyright 2010 All-Seeing Interactive. All rights reserved.
//
#import "RequestProgressCell.h"
@implementation RequestProgressCell
+ (id)cell
{
RequestProgressCell *cell = [[[RequestProgressCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"RequestProgressCell"] autorelease];
[[cell textLabel] setTextAlignment:UITextAlignmentLeft];
[[cell textLabel] setFont:[UIFont systemFontOfSize:12]];
[cell setProgressView:[[[UIProgressView alloc] initWithFrame:CGRectMake(0,0,100,20)] autorelease]];
[cell setAccessoryView:[cell progressView]];
return cell;
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect f = [[self accessoryView] frame];
[[self accessoryView] setFrame:CGRectMake(f.origin.x, f.origin.y+6, f.size.width, f.size.height)];
}
@synthesize progressView;
@end
... ...
... ... @@ -17,8 +17,10 @@
UITextView *responseField;
UISwitch *replaceURLsSwitch;
ASIWebPageRequest *request;
NSMutableArray *requestsInProgress;
}
- (void)fetchURL:(NSURL *)url;
@property (retain, nonatomic) ASIWebPageRequest *request;
@property (retain, nonatomic) NSMutableArray *requestsInProgress;
@end
... ...
... ... @@ -11,12 +11,13 @@
#import "ASIWebPageRequest.h"
#import "ASIDownloadCache.h"
#import "ToggleCell.h"
#import "RequestProgressCell.h"
@implementation WebPageViewController
- (void)fetchWebPage:(id)sender
{
[self fetchURL:[NSURL URLWithString:[urlField text]]];
}
- (void)clearCache:(id)sender
... ... @@ -27,6 +28,11 @@
- (void)fetchURL:(NSURL *)url
{
[urlField resignFirstResponder];
[self setRequestsInProgress:[NSMutableArray array]];
[[self tableView] reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationBottom];
// This allows our ASIDownloadCache to masquerade as as NSURLCache
// It allows the webView to load the content we downloaded when replaceURLsWithDataURLs is NO
[NSURLCache setSharedURLCache:[ASIDownloadCache sharedCache]];
... ... @@ -38,6 +44,7 @@
[request setDidFailSelector:@selector(webPageFetchFailed:)];
[request setDidFinishSelector:@selector(webPageFetchSucceeded:)];
[request setDelegate:self];
[request setDownloadProgressDelegate:self];
[request setShowAccurateProgress:NO];
[request setReplaceURLsWithDataURLs:[replaceURLsSwitch isOn]];
... ... @@ -68,6 +75,7 @@
[urlField setText:[[theRequest url] absoluteString]];
}
// We'll take over the page load when the user clicks on a link
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)theRequest navigationType:(UIWebViewNavigationType)navigationType
{
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
... ... @@ -77,6 +85,32 @@
return YES;
}
// At time of writing ASIWebPageRequests do not support automatic progress tracking across all requests needed for a page
// The code below shows one approach you could use for tracking progress - it creates a new row with a progress indicator for each resource request
// However, you could use the same approach and keep track of an overal total to show progress
- (void)requestStarted:(ASIWebPageRequest *)theRequest
{
[[self requestsInProgress] addObject:theRequest];
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:[[self requestsInProgress] count]-1 inSection:2]] withRowAnimation:UITableViewRowAnimationBottom];
[[self tableView] endUpdates];
}
- (void)request:(ASIHTTPRequest *)theRequest didReceiveBytes:(long long)newLength
{
NSInteger requestNumber = [[self requestsInProgress] indexOfObject:theRequest];
if (requestNumber != NSNotFound) {
RequestProgressCell *cell = (RequestProgressCell *)[[self tableView] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:requestNumber inSection:2]];
[[cell progressView] setProgress:[theRequest totalBytesRead]/([theRequest contentLength]+[theRequest partialDownloadSize])];
}
}
- (void)request:(ASIHTTPRequest *)theRequest incrementDownloadSizeBy:(long long)newLength
{
[self request:theRequest didReceiveBytes:0];
}
/*
Most of the code below here relates to the table view, and isn't that interesting
*/
... ... @@ -148,6 +182,18 @@ static NSString *intro = @"ASIWebPageRequest lets you download complete webpages
}
} else if ([indexPath section] == 2) {
cell = [tableView dequeueReusableCellWithIdentifier:@"RequestProgressCell"];
if (!cell) {
cell = [RequestProgressCell cell];
}
ASIHTTPRequest *theRequest = [[self requestsInProgress] objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[[theRequest url] absoluteString]];
if ([theRequest contentLength] > 0) {
[[(RequestProgressCell *)cell progressView] setProgress:[theRequest totalBytesRead]/([theRequest contentLength]+[theRequest partialDownloadSize])];
}
} else if ([indexPath section] == 3) {
cell = [tableView dequeueReusableCellWithIdentifier:@"Response"];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Response"] autorelease];
... ... @@ -156,7 +202,6 @@ static NSString *intro = @"ASIWebPageRequest lets you download complete webpages
}
[responseField setFrame:CGRectMake(5,5,tableWidth-tablePadding,180)];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
... ... @@ -204,6 +249,8 @@ static NSString *intro = @"ASIWebPageRequest lets you download complete webpages
{
if (section == 1) {
return 2;
} else if (section == 2) {
return [requestsInProgress count];
}
return 1;
}
... ... @@ -226,8 +273,10 @@ static NSString *intro = @"ASIWebPageRequest lets you download complete webpages
} else {
return 50;
}
} else {
} else if ([indexPath section] == 3) {
return 200;
} else {
return 34;
}
}
... ... @@ -238,8 +287,9 @@ static NSString *intro = @"ASIWebPageRequest lets you download complete webpages
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
return 4;
}
@synthesize request;
@synthesize requestsInProgress;
@end
... ...
This diff was suppressed by a .gitattributes entry.