iOS 7 UIWebView 无法渲染

28

我正在将我的应用移植到iOS 7,但在使用iOS 7的UIWebView时遇到了问题。 我使用以下代码加载本地html字符串:

NSURL *baseURL = [NSURL fileURLWithPath: DOCUMENTS_DIRECTORY];
[self.descWebView loadHTMLString:html baseURL:baseURL];

在iOS 6及以前的版本中它可以完美工作,但在iOS 7上它无法渲染,UIWebView仍然是白色的。控制台上会显示这个消息:

void SendDelegateMessage(NSInvocation *): delegate
(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)
failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
感谢您的回复。

1
[self.descWebView loadHTMLString:@"test" baseURL:[NSURL fileURLWithPath:DOCUMENTS_DIRECTORY]];-这样的代码对我来说很好用。问题可能来自于您的html内容,或者您实现的一些UIWebViewDelegate方法。 - alex-i
2
有趣的是,如果我存档应用并在设备中安装.ipa文件,在第一次运行时它不起作用,但是如果我从多任务中关闭应用并再次打开应用,则可以很好地运行... - usakc
1
我也遇到了同样的问题!在 iOS7 上,当我安装 .ipa 文件时,我的 webview 无法正常工作,并出现了与上述相同的错误。关闭并重启应用程序可以解决该问题!你找到了解决方案或解决方法吗? - Trunal Bhanse
10
我有同样的问题,与使用 Critterism SDK 有关。如果禁用它,一切都正常工作。 - zaplitny
你还有这个问题吗?我们这边不使用Critterism。 - Geraud.ch
我也遇到了这个问题,但我没有使用Critterism。 - powerj1984
10个回答

11

如@zaplitny所提到的,我需要将Crittercism更新到最新版本(4.1.0),才能解决这个问题。


1
这是真的吗?我无法相信是Bug跟踪器导致了这个bug! - neobie
1
这是真的。Crittercism 4.0.x版本存在一个限制,使其与iOS 7中的UIWebView不兼容。这在所有4.1.x版本中得到了修复。 - Jeremiah Edwards
4
我使用 Crittercism 4.1.1 (RC) 版本,遇到了这个问题。由于问题似乎有时出现有时又消失,我无法确定是否是 Crittercism 的问题,因此不能通过禁用/启用来确认。 - Merott
5
我刚刚联系了Crittercism支持团队。显然,这个问题已经在4.3.1版本中得到解决。 - nacross
我可以确认@nacross的评论。修复方法在Crittercism的发布说明中有概述:https://app.crittercism.com/downloads/release_notes/ios/4.3.1 - Jeremiah Edwards
显示剩余2条评论

9
Crittercism库的旧版本存在问题,导致了这个错误。正如其他人在评论中所提到的那样,这个bug已经在Crittercism SDK的4.3.1版中得到了修复。 https://app.crittercism.com/downloads/release_notes/ios/4.3.1
修复:针对在iOS 7上运行时遇到UIWebViews无法加载数据的应用程序的解决方法。该问题仅出现在子类化UIWebView的应用程序中(Crittercism已向Apple提交了一个bug报告)。注意-虽然您的应用程序可能没有直接子类化UIWebView,但这在许多常见的第三方库(如Google AdMob和Millenial Media SDK)中已经实现了。

2
对我来说重要的部分是“请注意,尽管您的应用程序可能不会直接子类化UIWebView,但许多常见的第三方库(如Google AdMob和Millenial Media SDK)会这样做。”谢谢。 - Jeremy Wiebe

7

对于那些更新了Crittercism到4.1.2版本,希望它能解决问题但实际上没有的人。我可以提供一个相当丑陋但简单的解决方案:在调用[Crittercism enableWithAppID:@"***...***"];之前创建和初始化UIWebView

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    ...
    UIWebView* fakeWebView = [[[UIWebView alloc] initWithFrame:CGRectMake(-1, -1, 1, 1)] autorelease];
    [fakeWebView loadHTMLString:@"<!DOCTYPE HTML><html><body>I need Crittercism</body></html>" baseURL:nil];
    [mainViewController.view addSubview:fakeWebView];

    [Crittercism enableWithAppID:@"***...***"];
    ...
}

这个技巧让我不仅解决了描述的问题,还略微加快了真正的 UIWebView 的初始加载速度。


1
这个可以运行,但不需要在UIWebView中加载内容或将其添加为子视图。只需初始化一个UIWebView即可产生相同的效果。 - Mihai Damian
1
这个问题在 Crittercism 版本 4.3.1 中已经完全修复。 - user235925

3

当我尝试展示Admob广告时,出现了这个错误。日志显示,只要启用Crittercism,就会出现该错误。值得一提的是,广告也无法正常显示。

为了解决这个问题,我禁用了Crittercism的工具,然而并非每个人都可以选择这种方法。

[Crittercism enableWithAppID:@"your_app_id" andDelegate:nil andURLFilters:nil disableInstrumentation:YES];

如果不想简单地创建一个Webview(您不需要将其添加为子视图),则像其他人建议的那样对我也有效。

[[UIWebView alloc] initWithFrame:CGRectMake(-1, -1, 1, 1)]
[Crittercism enableWithAppID:@"your_app_id"];

2
尝试使用product --> clean命令,这不会有任何损失。当您运行应用程序时,它只会replace/compile更改的文件。有时候xCode会出现错误,不会编译已更改的文件。Product clean会删除旧版本的编译代码,因此下次构建时将全部从上次编译开始。再次强调,这样做没有任何损失。

1
我在IOS7上使用PhoneGap应用程序时出现了类似的问题,必须在“viewDidAppear”或“Pageshow”上重新绘制页面UI,使用下面的代码解决了我的问题。
 $(".cls_div_page_content").redraw();
 jQuery.fn.redraw = function() {
   return this.hide(0, function(){$(this).show()});
 };

1
我看到你遇到的问题。我尝试过:
  • 将加载请求从viewDidLoad移动到viewWillAppear和viewDidAppear,但这没有帮助
  • 在加载请求后尝试重新加载webview,但仍然没有效果
  • 尝试将URL创建从URLWithString更改为fileURLWithPath,但仍然没有效果
更奇怪的是,当页面无法加载时,没有委托方法被触发。就好像webview甚至不尝试加载页面一样。但是,正如你所说,如果你从多任务视图中关闭应用程序并重新打开它,一切都正常。
你能找到解决方法或解决方案吗?

你找到解决方法了吗? - Geraud.ch
3
我做了一件事,问题是由Crittercism引起的。我通过从使用"enableWithAppID:"方法转换为使用"enableWithAppID:anDelegate:andURLFilters:disableInstrumentation:"方法来解决它。将委托和过滤器参数传递为nil,并将禁用仪器设置为true。 - SLEW
1
看起来它可以工作。但是“disableInstrumentation”参数是什么意思?我在Crittercism文档中没有找到任何关于此参数的信息。 - Igor Kulagin

1

很多时候,这个错误可能是由于您在使用某些特定iOS版本中不可用的东西。例如:

NSString *test=@"test this";

[test containsString:@"test"];

在iOS 7.1中使用containsString会产生相同的以下错误,但在iOS 8.0中可以正常工作:

void SendDelegateMessage(NSInvocation *): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:)在等待10秒后未能返回。主运行循环模式:kCFRunLoopDefaultMode。


1
我也遇到了这个问题。似乎问题是由于连接某些第三方库而引起的,但是我甚至不确定在我的情况下究竟是哪一个负责的。我的应用程序中没有Crittercism。
对我有帮助的是我在Apple Dev Forum上找到的建议,早期实例化UIWebView
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // In a severe case of WTF: some 3rd party libs (exact culprit unknown) can cause webviews to stop
    // showing anything on iOS 7, and instead have console warnings every 10 seconds that look like:
    // void SendDelegateMessage(NSInvocation *): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
    // Just instantiating an UIWebView before any of the 3rd party libs kick in is enough to fix it.
    // Don't know why, but it works.
    if (SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
        webView.delegate = nil; // Do something with webView to silence warning
    }
    return YES;
}

0

对于在iOS7/iOS8下使用Parse SDK 1.6.x版本且子类化UIWebView的人,如果您正在使用PFInstallation saveInBackground方法,则会出现相同的问题。

解决方案是延迟调用saveInBackground方法,例如:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3.f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [currentInstallation saveInBackground];
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接