Я занимаюсь разработкой приложения Objective C, которое загружает большой HTML-документ в UIWebView, когда пользователь просматривает его. Это связано с тем, что размер документа составляет 20 МБ, и он может привести к сбою веб-просмотра, если загружается все сразу. Идея состоит в том, что документ разбивается на куски HTML, и когда пользователь прокручивает его, в него добавляются новые элементы, а старые удаляются.
В настоящее время я работаю над тем, чтобы приложение Objective C передавало данные в функцию javascript внутри документа. У меня есть следующий код Objective 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();"]);
}
У меня есть следующий javascript в документе:
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;
}
Код Objective C запускается в событии $ (document) .ready () jQuery с использованием следующего кода:
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "js-call:loadNext");
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
Если я прошагаю по коду, то я вижу, что запускается метод stringByEvaluatingJavaScriptFromString, который либо возвращает «добавленный» в качестве результата, либо иногда возвращаемый указатель недопустим. В веб-представлении не отображаются оповещения, и html не добавляется в nextHtmlToAdd, кажется, что только первый бит HTML правильно передается в UIWebView.
Что мне было интересно, так это ли ограничение на длину строки javascript, которую может выполнять stringByEvaluatingJavaScriptFromString, или на количество раз, которое она может быть выполнена? Есть ли альтернативные способы сделать это?
Спасибо
Джо