问题描述
我正在开发一个Objective C应用程序,当用户滚动它时,它将大型HTML文档加载到UIWebView中。这是因为文档是20Mb,如果一次加载,往往会导致webview崩溃。我们的想法是将文档拆分为HTML块,当用户滚动浏览时,新元素将添加到文档中,旧元素将被删除。
I am developing an Objective C application that loads a large HTML document in to a UIWebView as the user scrolls through it. This is because the document is 20Mb and tends to crash the webview if loaded all at once. The idea is that the document is split in to chunks of HTML and as the user scrolls through it new elements are added to the document and old elements are removed.
目前我我正在努力让Objective C应用程序将数据传递给文档中的javascript函数。我有以下目标C代码:
Currently I am working on getting the Objective C application to pass data to a javascript function within the document. I have the following Objective C code:
- (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();"]);
}
我在文档中有以下javascript:
I have the following javascript within the document:
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;
}
目标C代码在jQuery的$(文档).ready()中触发使用以下代码的事件:
The Objective C code is triggered in jQuery's $(document).ready() event using the following code:
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "js-call:loadNext");
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
如果我单步执行代码,那么我看到的是运行stringByEvaluatingJavaScriptFromString方法并返回'附加' '结果或有时返回的指针无效。 Web视图中没有警报,并且html没有附加到nextHtmlToAdd,只有HTML的第一位似乎正在正确传递给UIWebView。
If I step through the code then what I see is the stringByEvaluatingJavaScriptFromString method being run and either returning 'appended' as a result or sometimes the returned pointer is invalid. No alerts appear within the web view and the html doesn't get appended to nextHtmlToAdd, only the first bit of HTML seems to be getting passed to the UIWebView correctly.
什么我想知道是否对stringByEvaluatingJavaScriptFromString可以执行的javascript字符串的长度或它可以执行的次数有限制?有没有其他方法可以做到这一点?
What I was wondering is if there is a limit on either the length of the javascript string that stringByEvaluatingJavaScriptFromString can execute or the number of times that it can be executed? Are there any alternative ways of doing this?
谢谢,
Joe
推荐答案
是的,对 stringByEvaluatingJavaScriptFromString
方法有限制。您需要了解的两个:
Yes, there are limits placed upon the stringByEvaluatingJavaScriptFromString
method. The two you need to know about:
- 不允许大于10MB的JavaScript分配
- JavaScript不允许执行时间超过10秒
在前者中,您将获得生成的异常,但在后者中它可能会默默地失败。您是否正在测试该方法的返回值?如果失败,它将返回 nil
。由于上述原因之一,这可以是查看脚本是否被操作系统终止的有用方法。
In the former, you'll get an exception generated, but in the latter it may well fail 'silently'. Are you testing the return value of the method? If it fails it will return nil
. This can be a useful way to see if your script is being terminated by the OS due to one of the reasons above.
这篇关于stringByEvaluatingJavaScriptFromString似乎并不总是有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!