2009-07-24 1 views
1

iPhone/objC? 응답을 검사하는 동안 webView : shouldStartLoadWithRequest : naviagiontType ... wait?

나는 정말로 여기에서 붙어있어서 약간의 도움을받을 수 있습니다.

내가 먼저 몇 가지를 설명하자

내가 URL을로드하는있는 UIWebView 있습니다. 사용자가 링크를 클릭하면 - (BOOL) webView : shouldStartLoadWithRequest : navigationType : 메시지를 가져옵니다 (프로토콜에 따름). 이 메서드 내에서 url이 webView에로드되어야하는지 또는 다른 것을 수행해야 하는지를 결정할 수 있습니다. 응답을 검사 할 수 있도록 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; 
    } 
} 

- (무효) 연결 : didReceiveResponse는 (프로토콜에 따라)가 메시지를 가져옵니다 내가 거기에 응답을 분석 할 수 있습니다. didReceiveResponse : 준비 (무효) 연결 -까지 기다리 : shouldStartLoadWithRequest : (BOOL) 웹보기를 -

- (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]; 

지금 내가 무엇을 달성하기 위해 노력하고있어 수 있도록하는 것입니다.

sendSynchronousRequest와 함께 작업 할 수 있습니다. 응답을 검사하기 전에 전체 파일을 다운로드해야합니다.

누구나 아이디어가 있습니까? 미리 감사드립니다. 또는 응답을 조사하는 더 좋은 방법이 있습니까?

답변

6

정말 원하는 경우 - (BOOL) webView : shouldStartLoadWithRequest : 두 가지 옵션이 있습니다. 첫 번째는 동 기적으로 데이터를로드 할 수 있습니다 :

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

당신은 (그들이 호출되지 않습니다 같은) 대리자 메서드를 구현하지 않아도 그렇게한다면. 그런 다음 응답을 다운로드할지 여부를 확인하는 메소드에 전달합니다.

당신이로드하는 동안 실행중인 runloop은 UI가 응답하지 않는 것을 의미하며, 느린 연결 인 경우 앱이 중지 될 수 있기 때문에 살해 될 수 있다는 단점이 있습니다 너무 오랫동안 이벤트에 응답.

다른 옵션은 웹보기의 내부에 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는 여전히 이벤트에 응답 할 수있을뿐만 아니라 완전히 상호 작용할 수 있습니다. 즉, 사용자가이 작업을 수행하는 동안 더 많은 링크를 사용할 수 있습니다. 재진입 코드를 작성하거나 문제를 일으킬 수있는 요소에 대해 사용자 상호 작용을 비활성화하여 자신을 보호해야합니다.

어느 쪽이든 주위에 두 가지 접근 방식 중 하나가 있습니다. 이것은 실제로 다소 복잡합니다. 경험 많은 코코아 개발자가 아니라면 그렇게하는 것을 권장하지 않습니다. 다운로드 프로세스를 처리하는 다른 방법을 찾을 수 있다면 훨씬 더 간단해질 것입니다.

+0

대단히 감사합니다! 나는 오늘 그것을 시도하고 쉬운 방법에 대해 생각하기 때문에 나는 아주 새로운 것을 개발할 것이다. 단지 2 주간의 경험 : D – Yllier

+0

가 방금 해봤습니다. 그것은 위대한 작품이지만, 지금은 내 생각이 그렇게 좋지 않다는 것을 알았습니다. 예를 들어 사람들이 포럼에 게시하려고하면 게시물을 두 번 게시하거나 오류 메시지가 나타납니다. – Yllier