有没有人发现某些URL的UIWebView失败了?

Red*_*ing 16 iphone uiwebview

我已经在iPhone应用程序上工作了几个星期,我添加的早期功能之一是UIWebView,它加载了上下文敏感的维基百科页面主题.这实现起来非常简单,并且已经工作了一段时间.

今天,我发现功能意外地停止了工作.我一直在那段代码的周边摆弄,最初认为我已经破坏了一些东西.

我检查了所有显而易见的地方,我的网址是UIWebView仍然连接在XIB等.我没有发现任何问题.

进一步调查,我在我的UIWebViewDelegate didFailLoadWithError上遇到了一些错误处理,发现我收到了-999错误:

NSURLErrorCancelled

取消异步加载时返回.

Web Kit框架委托在对加载资源执行取消操作时将收到此错误.请注意,如果取消下载,NSURLConnection或NSURLDownload委托将不会收到此错误.

所以这听起来像是在原始请求完成之前发出新请求(或取消).我检查我的代码是否有这样的东西,然后空出来.

因此,我进入了惯常的偏执狂,并假设维基百科正在阻止基于UAgent或其他东西的请求,并继续进行一些疯狂的追逐,试图欺骗我回到幸福的地方.这些尝试没有成功,最终理智得到了胜利.我创建了一个简单的python脚本来模仿我在模拟器中从我的APP发出的HTTP请求,看看维基百科发回的内容:

string = "GET /wiki/Franklin_D._Roosevelt HTTP/1.1\r\nHost: en.wikipedia.org\r\nUser-Agent: test\r\nReferer: http://en.wikipedia.org/wiki/Franklin_D._Roosevelt\r\nAccept: */*\r\nAccept-Language: en-us\r\n_Accept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\n\r\n"
import socket
s = socket.socket()
s.connect(("en.wikipedia.org",80))
s.send(string)
x = s.recv (1000)
while (x):
    print x
    x = s.recv (1000)
Run Code Online (Sandbox Code Playgroud)

所以我运行这个人,发现维基百科非常友好地及时完整地返回我的数据.那么发生了什么?

Chinks开始出现在我的每一个礼物,偏执的盔甲"这总是我的错",我决定检查其他iPhone应用程序是否可以查看这些URL.我发布了一条带有讽刺意味(我很容易被逗乐)URL 的推文,并查看Tweetie是否可以查看该网址.它不能.

一位朋友在Twitterific中试一试.同样的问题.在Safari和维基百科应用程序中工作正常,但似乎使用沼泽标准UIWebView的 iPhone应用程序在维基百科页面上遇到问题.

为了完全确定没有其他变量,我创建了一个简单的测试应用程序,只加载了一个UIWebViewhttp://en.wikipedia.com,它失败并出现相同的错误(最后添加了代码).

那你觉得怎么样?这只是一个UIWebView错误吗?任何苹果公司的人都知道这里发生了什么事吗?

我是否错过了一些完全明显的东西,我再次坐在火车上工作,没穿裤子?

期待听到您的想法.请记住,这昨天工作正常.

汇报(或者说Post Mortem更合适):

感谢Duncan提供的解决方案以及对此处发生的事情的清晰描述.

看起来我最初看到错误的原因,当我没有实现didFailLoadWithError委托方法时,该方法的默认行为显然是清除UIWebView并因此终止请求.当我添加我的实现以了解发生了什么时,我坚持使用一些代码将错误写入视图,正如Duncan指出的那样,这就是我得到的结果.

看起来像是一个非常可怕的解决方案,在回调中忽略了-999错误代码,但我对胶带很好.

我尝试了很多应用程序来测试这是否是一个UIWebView问题(Tweetie,Twitteriffic等...),他们都有问题.看起来这对开发人员来说可能是一个非常常见的疏忽.也许Apple可以在下一个版本中清理它.

其他有趣的一点是,当我将我的URL切换为使用http://en.m.wikipedia.com而不是http://en.wikipedia.com时,问题就消失了.

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    _webView = (UIWebView*)self.view;
    _webView.delegate = self;

    // load the url

    // FAIL
    //NSURL * newUrl = [[[NSURL alloc] initWithString:@"http://en.wikipedia.com"] autorelease];

    // OK
    NSURL * newUrl = [[[NSURL alloc] initWithString:@"http://www.stackoverflow.com"] autorelease];

    NSURLRequest * newUrlRequest = [NSURLRequest requestWithURL:newUrl];
    [_webView loadRequest:newUrlRequest];                                    
}

// delegate stuff
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)req navigationType:(UIWebViewNavigationType)navigationType { return YES; }
- (void)webViewDidStartLoad:(UIWebView *)wv
    {
    // starting the load, show the activity indicator in the status bar
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // finished loading, hide the activity indicator in the status bar
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSURLErrorDomain
    // load error, hide the activity indicator in the status bar
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [_webView loadHTMLString:[[[NSString alloc] initWithFormat:@"Failed to load page %@", [error localizedDescription]] autorelease] baseURL:nil];
}
Run Code Online (Sandbox Code Playgroud)

dun*_*cox 17

看起来这里有一个答案:

如何在iPhone 3.0操作系统中修复NSURLErrorDomain错误-999

反过来又指:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/6280-uiwebview-didfailloadwitherror-how-get-errors-code-list.html

看起来你需要在webView中使用这样的hack:didFailLoadWithError:delegate:

if ([error code] != NSURLErrorCancelled) {
    //show error alert, etc.
}
Run Code Online (Sandbox Code Playgroud)

本质上发生的事情是委托正在获得"取消"(-999)失败,这可能源于javascript或者甚至是UIWebView错误.

使用您的代码,webview根本不显示任何内容,因为您使用的是相同的UIWebView来显示错误.如果你只是NSLog的错误,你会看到失败,但然后页面将加载很好,给你一个暗示失败是假的.