有没有人发现 UIWebView 对于某些 URLS 失败? [英] Has anyone found that UIWebView fails for some URLS?

查看:12
本文介绍了有没有人发现 UIWebView 对于某些 URLS 失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

<块引用>

NSURLErrorCancelled

异步加载时返回取消.

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

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

所以我进入了我通常的偏执下降螺旋,并假设 Wikipedia 正在阻止基于 UAgent 或其他东西的请求,并继续进行一些疯狂的追逐,试图欺骗我回到一个快乐的地方.这些尝试没有成功,最终理智占了上风.我创建了一个简单的 python 脚本来模拟我在模拟器中从我的 APP 发出的 HTTP 请求,以查看 Wikipedia 发回的内容:

string = "GET/wiki/Franklin_D._Roosevelt HTTP/1.1
Host: en.wikipedia.org
User-Agent: test
Referer: http://en.wikipedia.org/wiki/Franklin_D._Roosevelt
Accept: */*
Accept-Language: en-us
_Accept-Encoding: gzip, deflate
Connection: keep-alive

"导入套接字s = socket.socket()s.connect(("en.wikipedia.org",80))s.发送(字符串)x = s.recv (1000)而(x):打印 xx = s.recv (1000)

所以我运行了这个人,发现 Wikipedia 非常友好地及时完整地返回我的数据.那到底是怎么回事?

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

一位朋友在 Twitterific 中试用.同样的问题.在 Safari 和 Wikipedia 应用程序中运行良好,但似乎使用沼泽标准 UIWebView 的 iPhone 应用程序在 Wikipedia 页面上存在问题.

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

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

我是否错过了一些非常明显的事情,我又一次坐在火车上不穿裤子去工作?

期待听到您的想法.请记住,昨天运行良好.

汇报(或者尸检更合适):<​​/p>

感谢 Duncan 提供解决方案以及对这里发生的情况的清晰描述.

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

在回调中忽略 -999 错误代码似乎是一个非常糟糕的解决方案,但我可以使用胶带.

我尝试了很多应用程序来测试这是否是 UIWebView 问题(Tweetie、Twitteriffic 等......),他们都遇到了问题.看起来这对于开发人员来说可能是一个非常普遍的疏忽.也许苹果可以在下一个版本中解决这个问题.

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

//实现 viewDidLoad 以在加载视图后进行额外设置,通常从 nib 加载.- (void)viewDidLoad {[超级视图DidLoad];_webView = (UIWebView*)self.view;_webView.delegate = 自我;//加载网址//失败//NSURL * newUrl = [[[NSURL alloc] initWithString:@"http://en.wikipedia.com"] autorelease];//行NSURL * newUrl = [[[NSURL alloc] initWithString:@"http://www.stackoverflow.com"] autorelease];NSURLRequest * newUrlRequest = [NSURLRequest requestWithURL:newUrl];[_webView loadRequest:newUrlRequest];}//委托东西- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)req navigationType:(UIWebViewNavigationType)navigationType { return YES;}- (void)webViewDidStartLoad:(UIWebView *)wv{//开始加载,在状态栏中显示活动指示器[UIApplication sharedApplication].networkActivityIndi​​catorVisible = YES;}- (void)webViewDidFinishLoad:(UIWebView *)webView{//加载完成,隐藏状态栏中的活动指示器[UIApplication sharedApplication].networkActivityIndi​​catorVisible = NO;}- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{NSURLErrorDomain//加载错误,隐藏状态栏中的活动指示器[UIApplication sharedApplication].networkActivityIndi​​catorVisible = NO;[_webView loadHTMLString:[[[NSString alloc] initWithFormat:@"加载页面失败 %@", [错误本地化描述]] autorelease] baseURL:nil];}

解决方案

看来这里有答案了:

如何修复 NSURLErrorDomainiPhone 3.0 操作系统中的错误 -999

又指:

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

看起来你需要在 webView:didFailLoadWithError:delegate:

if ([error code] != NSURLErrorCancelled) {//显示错误警报等}

本质上,发生的事情是委托出现已取消"(-999) 故障,这可能源于 javascript,甚至可能源于 UIWebView 错误.

使用您的代码,webview 根本不显示任何内容,因为您使用的是相同的 UIWebView 来显示错误.如果您刚刚 NSLog'd 错误,您会看到失败,但是页面会加载得很好,提示您失败是假的.

I have been working on an iPhone App for a couple of weeks now and one of the earlier features I added was a UIWebView that loaded context sensitive Wikipedia page topics. This was pretty trivial to implement and has been working fine for some time.

Today, I found that functionality had unexpectedly stopped working. I had been fiddling around at the perimeter of that piece of code and initially assumed that I had broken something.

I checked all the obvious places, my urls, was the UIWebView still hooked up in the XIB etc. I didn't find any issues.

Investigating further, I stuck some error handling on my UIWebViewDelegate didFailLoadWithError and found I was getting a -999 error:

NSURLErrorCancelled

Returned when an asynchronous load is canceled.

A Web Kit framework delegate will receive this error when it performs a cancel operation on a loading resource. Note that an NSURLConnection or NSURLDownload delegate will not receive this error if the download is canceled.

So this sounds like making a new request (or cancelling) before the original one has finished. I check my code for anything like this and come up empty.

So I went into my usual downward spiral of paranoia and assumed that Wikipedia was blocking requests based on UAgent or something and went on something of wild goose chase attempting to spoof my way back to a happy place. These attempts were not successful and eventually sanity prevailed. I created a simple python script to mimic the HTTP request I was making from my APP in the simulator, to see what Wikipedia was sending back:

string = "GET /wiki/Franklin_D._Roosevelt HTTP/1.1
Host: en.wikipedia.org
User-Agent: test
Referer: http://en.wikipedia.org/wiki/Franklin_D._Roosevelt
Accept: */*
Accept-Language: en-us
_Accept-Encoding: gzip, deflate
Connection: keep-alive

"
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)

So I run this guy and discover that Wikipedia is very kindly returning my data promptly and completely. So what is going on?

Chinks started to appear in my every present, paranoid armour "It's always my fault" and I decide to check out if other iPhone apps can view these URLs. I post a tweet with an ironically amusing (I am easily amused) URL and check out if Tweetie can view the URL. It can't.

A friend tries it out in Twitterific. Same problem. Works fine in Safari and the Wikipedia App, but it seems like iPhone apps using a bog standard UIWebView are having problems with Wikipedia pages.

Just to be completely certain there are no other variables, I created a simple test app with just a UIWebView that loads up http://en.wikipedia.com, it fails with the same error (added that code at the end).

So what do you guys think? Is this just a UIWebView bug? Any Apple gronks out there know what is going on here?

Have I missed something completely obvious and I am once again sitting on the train to work without my pants on?

Looking forward to hearing what you think. Keep in mind, this was working fine yesterday.

Debrief (or maybe Post Mortem is more appropriate):

Thanks Duncan for the solution and a pretty clear description of what is going on here.

Looks like the reason I originally saw the error, when I wasn't implementing the didFailLoadWithError delegate method at all, was that the default behavior for that method is apparently to clear the UIWebView and consequently kill the request. When I added my implementation to find out what was going on, I stuck in some code to write the error to the view and, as Duncan points out, this is what got me.

Seems like a pretty horrible solution to ignore -999 error codes in the callback, but I am fine with duct tape.

I tried quite a few apps to test if this was a UIWebView problem (Tweetie, Twitteriffic etc ...) and they all had the issue. It looks like this might be a pretty common oversight for developers. Maybe Apple can clean this up in the next version.

Other interesting point is that when I switched my URLs to use http://en.m.wikipedia.com instead of http://en.wikipedia.com, the problem went away.

// 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];
}

解决方案

Looks like there's an answer here:

How do I fix NSURLErrorDomain error -999 in iPhone 3.0 OS

which in turn refers to:

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

Looks like you need a hack like this in the webView:didFailLoadWithError: delegate:

if ([error code] != NSURLErrorCancelled) {
    //show error alert, etc.
}

In essence what's happening is the delegate is getting a "cancelled" (-999) failure, that might be originated in javascript or perhaps even in a UIWebView bug.

With your code the webview doesn't show anything at all because you're using the very same UIWebView to display the error. If you had just NSLog'd the error you would have seen a failure, but then the page would have loaded just fine, giving you a hint that the failure is bogus.

这篇关于有没有人发现 UIWebView 对于某些 URLS 失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆