Iphone ?在webView:shouldStartLoadWithRequest:NaviAgionType。。。等待?
iPhone/objC 我真的被困在这里了,我需要一些帮助 让我先解释一些事情: 我有一个加载url的UIWebView。用户单击链接后-(BOOL)webView:shouldStartLoadWithRequest: navigationType:获取消息(根据协议)。在这个方法中,我可以决定是在webView中加载url,还是用它做其他事情。我正在建立一个NSURLConnection,以便检查响应Iphone ?在webView:shouldStartLoadWithRequest:NaviAgionType。。。等待?,iphone,objective-c,nsurlconnection,Iphone,Objective C,Nsurlconnection,iPhone/objC 我真的被困在这里了,我需要一些帮助 让我先解释一些事情: 我有一个加载url的UIWebView。用户单击链接后-(BOOL)webView:shouldStartLoadWithRequest: navigationType:获取消息(根据协议)。在这个方法中,我可以决定是在webView中加载url,还是用它做其他事情。我正在建立一个NSURLConnection,以便检查响应 - (BOOL)webView:(UIWebView*)webView shouldSta
- (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)connection: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:didReceiverResponse:准备就绪。
我可以使用sendSynchronousRequest:因为它会在我检查响应之前下载完整的文件
- (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;
}
}
有人有主意吗?提前谢谢。
或者有更好的方法来检查响应吗?如果你真的想-(BOOL)webView:shouldStartLoadWithRequest:你有两个选择。首先,您可以同步加载数据:
NSData * receivedDataFromConnection = [NSURLConnection sendSynchronousRequest: request returningResponse:&response error:&error];
如果这样做,就不必实现委托方法(因为它们不会被调用)。然后,您只需将响应传递到一个方法中,该方法检查您是否要下载
这样做的缺点是,如果你这样做,你将在加载时玩runloop,这意味着UI将变得无响应,如果你的连接速度慢,应用程序可能会被杀死,因为它将停止响应事件太长时间
另一个选项是在webView: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开发者,我不建议你这么做,如果你能找到其他方法来处理你的下载过程,它会简单得多。如果你真的想-(BOOL)webView:shouldStartLoadWithRequest:你有两个选择。首先,您可以同步加载数据:
NSData * receivedDataFromConnection = [NSURLConnection sendSynchronousRequest: request returningResponse:&response error:&error];
如果这样做,就不必实现委托方法(因为它们不会被调用)。然后,您只需将响应传递到一个方法中,该方法检查您是否要下载
这样做的缺点是,如果你这样做,你将在加载时玩runloop,这意味着UI将变得无响应,如果你的连接速度慢,应用程序可能会被杀死,因为它将停止响应事件太长时间
另一个选项是在webView: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开发人员,我不建议您这样做,如果您能找到其他方法来处理下载过程,它会简单得多。非常感谢!今天我将尝试一下,并考虑更简单的方法,因为我对开发非常陌生。只有两周的经验:Djust试过了。它工作得很好,但现在我注意到我的想法不太好。例如,如果有人试图在论坛上发帖,他们会加倍发帖或收到错误消息……非常感谢!今天我将尝试一下,并考虑更简单的方法,因为我对开发非常陌生。只有两周的经验:Djust试过了。它工作得很好,但现在我注意到我的想法不太好。例如,如果人们试图在论坛上发表文章,他们会重复发表文章或收到错误消息。。。