2011-09-12 3 views
1

사용자가 스크롤 할 때 큰 HTML 문서를 UIWebView로로드하는 Objective C 애플리케이션을 개발 중입니다. 이것은 문서가 20MB이기 때문에 한꺼번에로드되면 웹보기가 손상되기 쉽기 때문입니다. 아이디어는 문서가 HTML 덩어리로 나뉘어져 사용자가 스크롤하면서 새로운 요소가 문서에 추가되고 이전 요소가 제거된다는 것입니다.stringByEvaluatingJavaScriptFromString이 항상 작동하지 않는 것처럼 보입니다.

현재 Objective C 응용 프로그램에서 문서 내의 JavaScript 함수에 데이터를 전달하는 중입니다. 나는 다음과 같은 목적 C 코드가 있습니다

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

NSString *url = [[request URL] absoluteString]; 
// Intercept custom location change, URL begins with "js-call:" 
if ([url hasPrefix:@"js-call:"]) { 

    // Extract the selector name from the URL 
    NSArray *components = [url componentsSeparatedByString:@":"]; 
    NSString *function = [components objectAtIndex:1]; 

    // Call the given selector 
    [self performSelector:NSSelectorFromString(function)]; 

    // Cancel the location change 
    return NO; 
} 

// Accept this location change 
return YES; 

} 

- (void)loadNext { 
int endIndex = [self.partIndexEnd intValue]; 
int newEndIndex = endIndex + 9; 
if (newEndIndex >= [self.parts count] - 2){ 
    newEndIndex = [self.parts count] - 2; 
} 
if (endIndex == newEndIndex){ 
    return; // Already at the end of the document 
} 

int splitLen = 300; 
NSRange range = NSMakeRange(endIndex, newEndIndex - endIndex); 
for (NSString *html in [self.parts subarrayWithRange:range]) { 
    NSLog(@"%@", html); 
    NSString *htmlToSplit = html; 
    while ([htmlToSplit length] > 0) { 
     NSString *curHtml; 
     if ([htmlToSplit length] <= splitLen){ 
      curHtml = htmlToSplit; 
      htmlToSplit = @""; 
     } 
     else { 
      curHtml = [htmlToSplit substringToIndex:splitLen + 1]; 
      htmlToSplit = [htmlToSplit substringFromIndex:splitLen - 1]; 
     } 

     NSString* result = [self.web stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"next('%@');", [curHtml gtm_stringByEscapingForAsciiHTML]]]; 

     NSLog(@"START %@ END %@", curHtml, result); 
    } 

} 
[self.web stringByEvaluatingJavaScriptFromString:@"next(null);"]; 
NSLog(@"HTML = %@ *END*", [self.web stringByEvaluatingJavaScriptFromString:@"$('body').html();"]); 
} 

을 내가 가지고있는 문서 내에서 다음과 같은 자바 스크립트 : 목표 C 코드를 사용하여 jQuery의 $ (문서) .ready() 이벤트에서 트리거

var nextHtmlToAdd = ''; 
function next(html){ 
    var retval = ''; 
    try{ 
      if (html){ 
        if (html.match(/teststring/i)){ 
          alert('teststring'); 
        } 
        nextHtmlToAdd = nextHtmlToAdd + html; 
        retVal = 'appended'; 
        alert(html); 
      } else { 
        // Finished sending HTML 
        alert('finished'); 
        if (nextHtmlToAdd.match(/teststring/i)){ 
          alert('encoded html contains teststring'); 
        } 

        nextHtmlToAdd = $("<div/>").html(nextHtmlToAdd).text(); 
        if (nextHtmlToAdd.match(/teststring/i)){ 
          alert('html contains teststring'); 
        } 
        alert(nextHtmlToAdd); 
        var elem = $(nextHtmlToAdd); 
        $('.endofsections').before(elem); 
        if (elem.text().match(/teststring/i)){ 
          alert('element contains teststring'); 
        } 
        if ($(document).text().match(/teststring/i)){ 
          alert('document contains teststring'); 
        } 
        nextHtmlToAdd = ''; 
        retVal = 'finished'; 
      } 
    } catch (err) { 
      alert('Error: ' + err.description); 
      retVal = 'error'; 
    } 
    return retVal; 
} 

다음 코드 : 다음 코드를 단계별 경우

var iframe = document.createElement("IFRAME"); 
iframe.setAttribute("src", "js-call:loadNext"); 
document.documentElement.appendChild(iframe); 
iframe.parentNode.removeChild(iframe); 
iframe = null; 

은 내가 볼 것은 stringByEvaluatingJavaScriptFromString 방법 인 실행과 중 t 결과로 때로는 '추가'반환 그가 반환 한 포인터가 유효하지 않습니다. 웹보기에는 경고가 표시되지 않고 HTML이 nextHtmlToAdd에 추가되지 않으며 첫 번째 비트 만 UIWebView로 올바르게 전달되는 것으로 보입니다.

내가 궁금한 것은 stringByEvaluatingJavaScriptFromString이 실행할 수있는 javascript 문자열의 길이 또는 실행될 수있는 횟수에 제한이 있다면 궁금한 것이 있습니까? 이 작업을 수행 할 수있는 대체 방법이 있습니까?

감사합니다,

답변

4

예, stringByEvaluatingJavaScriptFromString 방법에 배치 한계가있다. 두 사람은 당신이 알 필요가 약 : 실행하는 데 10 초보다 오래 걸리는

  • 자바 스크립트가 이전에

  • 을, 당신은 것입니다 허용되지 않습니다 허용되지 않습니다 10메가바이트보다 큰

    • 자바 스크립트 할당 생성 된 예외를 얻지 만, 후자에서는 '조용히'실패 할 수 있습니다. 메서드의 반환 값을 테스트하고 있습니까? 실패하면 nil을 반환합니다. 위의 이유로 스크립트가 OS에 의해 종료되는지 여부를 확인하는 데 유용합니다.

    +0

    도움 주셔서 감사합니다. 10Mb가 넘을 때 나는 [web stringByEvaluatingJavaScriptFromString : @ "var x = '1234567890 ..... 10Mb 상당의 데이터를 얻을 수 있다는 것을 의미합니까?"]? 그렇다면 그것은 내 모든 문제를 해결합니다. – JoeS

    +0

    아니요, 10MB는 전달되는 문자열의 크기를 나타내지 않으며 실행 중 JavaScript의 메모리 사용량을 나타냅니다. 따라서 HTML 문서의 크기가 20MB이고 JavaScript가 전체 문서를 가져와야하는 경우 사전에 문제가 발생할 수 있습니다. 한 번에 모든 문서를 메모리에로드하는 대신 문서를로드/스캔하는 방법을 알아야합니다. – lxt

    +0

    아, 알겠습니다. 그것은 기본적으로 내가하려는 일입니다. stringByEvaluatingJavaScriptFromString에 전달할 수있는 문자열의 길이에 제한이 무엇인지 알 수 있습니까? 현재 300 바이트 청크로 문서를로드 중입니다. – JoeS

    관련 문제