?检查webView时的响应:shouldStartLoadWithRequest:naviagiontType ...等待?

时间:2009-07-24 10:53:59

标签: iphone objective-c nsurlconnection

iPhone / objC

我真的被困在这里,我可以帮忙。

首先让我解释一下:

我有一个加载网址的UIWebView。一旦用户点击链接 - (BOOL)webView:shouldStartLoadWithRequest:  navigationType:获取消息(根据协议)。在这个方法中,我可以决定是否应该在webView中加载url或者使用它做其他事情。我正在建立一个NSURLConnection,所以我可以检查一下。

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
 navigationType:(UIWebViewNavigationType)navigationType {

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (theConnection) {
        NSLog(@" Connection established");
        receivedDataFromConnection = [[NSMutableData data] retain];
        }
    else {
        NSLog(@"Connection failed");
    }   


    if (downloadYESorNO == YES) {
        NSLog(@"Do the download");
        return NO;
    }
    else {
        NSLog(@"will show in webView");
        return YES;
    }
}

一旦应用程序获得响应 - (void)连接:didReceiveResponse:获取消息(根据协议),我可以在那里分析响应。

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{      
        NSString *MIME = response.MIMEType;
        NSString *appDirectory = [[NSBundle mainBundle] bundlePath];
        NSString *pathMIMETYPESplist = [appDirectory stringByAppendingPathComponent:@"MIMETYPES.plist"];

        NSArray *displayMIMETypes = [NSArray arrayWithContentsOfFile: pathMIMETYPESplist];
        BOOL *asdf = [displayMIMETypes containsObject:MIME];

        if (asdf == YES) {
            downloadYESorNO =NO;
        }
        else {
            downloadYESorNO = YES;
        }

        [receivedDataFromConnection setLength:0];
        [connection release];

现在我想要实现的是 - (BOOL)webView:shouldStartLoadWithRequest:等到 - (void)connection:didReceiveResponse:准备就绪。

我可以使用sendSynchronousRequest:因为它会在我检查响应之前下载完整的文件。

有没有人有想法?提前致谢。 还是有更好的方法来检查反应?

1 个答案:

答案 0 :(得分:6)

如果你真的想要 - (BOOL)webView:shouldStartLoadWithRequest:你有两个选择。首先,您可以同步加载数据:

NSData * receivedDataFromConnection = [NSURLConnection sendSynchronousRequest: request  returningResponse:&response error:&error];

如果这样做,则不必实现委托方法(因为它们不会被调用)。然后,您只需将响应传递给检查是否要下载的方法。

缺点是,如果你这样做,你将在加载时运行runloop,这意味着UI将变得无响应,如果你的连接速度很慢,应用程序可能会被杀死,因为它会停止响应事件太久了。

另一个选项是在webView中运行runLoop:shouldStartLoadWithRequest:navigationType:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
 navigationType:(UIWebViewNavigationType)navigationType {

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (theConnection) {
        NSLog(@" Connection established");
        receivedDataFromConnection = [[NSMutableData data] retain];
        }
    else {
        NSLog(@"Connection failed");
    }   

     waitingForResponse = YES;
     while (waitingForResponse) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        [pool drain];
    }


    if (downloadYESorNO == YES) {
        NSLog(@"Do the download");
        return NO;
    }
    else {
        NSLog(@"will show in webView");
        return YES;
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{      
    NSString *MIME = response.MIMEType;
    NSString *appDirectory = [[NSBundle mainBundle] bundlePath];
    NSString *pathMIMETYPESplist = [appDirectory stringByAppendingPathComponent:@"MIMETYPES.plist"];

   NSArray *displayMIMETypes = [NSArray arrayWithContentsOfFile: pathMIMETYPESplist];
   BOOL *asdf = [displayMIMETypes containsObject:MIME];

   if (asdf == YES) {
         downloadYESorNO =NO;
   } else {
        downloadYESorNO = YES;
   }

   [receivedDataFromConnection setLength:0];
   [connection release];
   waitingForResponse = NO;
}

通过执行runloop,您可以继续执行事件处理,从而调用您的委托方法。显然,你需要检测它何时完成并停止运行runloop,这就是waitingForResponse ivar的用途。

因为你的runloop正在运行,UI不仅仍然能够响应事件,而且完全是交互式的。这意味着用户可以在执行此操作时点击更多链接。您需要通过使代码可重入,或通过禁用用户交互来解决任何可能导致问题的任何事情来保护自己。

无论哪种方式,都有很多陷阱要么接近。这真的是一个有点复杂的事情,如果你不是一个经验丰富的Cocoa开发人员,我不建议这样做,如果你能找到一些其他方式来处理你的下载过程,那将会更加简单。