2009-10-16 11 views
16

私は数週間前からiPhoneアプリケーションを開発していましたが、私が追加した以前の機能の1つはUIWebViewであり、コンテキスト依存Wikipediaのページのトピックが読み込まれました。これは実装が非常に簡単で、しばらくの間うまくいっています。誰かが、UIWebViewがいくつかのURLで失敗することを発見しましたか?

今日、機能が予期せず動作しなくなったことがわかりました。私はそのコードの周りをぐるぐる回っていて、最初は何かが壊れていると想定していました。

私のすべての明白な場所を確認したところ、UIWebViewはまだXIBなどに接続されていましたが、問題は見つかりませんでした。さらに調査

は、私は私のUIWebViewDelegatedidFailLoadWithErrorに扱ういくつかのエラーが立ち往生し、私は-999エラーを取得しましたが見つかりました:

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.

は、これは新しい要求を行う(またはキャンセル)のように聞こえるの前に元のものは終了しました。私はこのようなものを自分のコードをチェックし、空になる。

私はいつもパラノイアの下向きの渦巻きに入って、ウィキペディアがUAgentや何かに基づいてリクエストをブロックしていて、幸せな場所に自分の道を戻そうとしている何かの野生のガチョウの追跡に行ったと仮定しました。これらの試みは成功せず、最終的には正気が勝った。私はウィキペディアが返送されたかを確認するために、私はシミュレータで、私のAPPから作っていたHTTPリクエストを模倣するために、簡単なPythonスクリプトを作成しました:

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) 

は、だから私はこの男を実行し、ウィキペディアは非常に親切に私を返していることを発見しますデータをすばやく完全に保存します。では何が起こっているのですか?

私の現在のすべての妄想鎧にはチンクスが現れ始めました。「それはいつも私のせいです」と、私は他のiPhoneアプリがこれらのURLを見ることができるかどうかチェックします。私はtweetを皮肉って面白い(私は簡単に面白い)URLで投稿し、TweetieがURLを見ることができるかどうかチェックする。それはできません。

友人がTwitterificで試してみます。同じ問題。 SafariとWikipedia Appで正常に動作しますが、それはiPhoneアプリケーションのようなものです。UIWebViewはWikipediaのページに問題があります。

ただ、他の変数が存在しない、完全に特定するためには、私はhttp://en.wikipedia.comをアップロードするだけのUIWebViewでsimple test appを作成し、それが同じエラーで失敗します(最後にそのコードを追加しました)。

あなたはどう思いますか?これはちょうどUIWebViewバグですか?ここで何が起こっているのか、アップルの専門家が知っていますか?

私は完全に明白な何かを逃したと私は再び、私のズボンなしで動作するように電車に座っている?

あなたの考えを聞くのを楽しみにしています。昨日、これはうまくいきました。ソリューションと、ここで何が起こっているかのかなり明確な説明のための

おかげDuncan

成果報告(または多分死後がより適切です)。

私はもともと私は全然didFailLoadWithErrorデリゲートメソッドを実装していなかったエラーを、見た理由は、そのメソッドのデフォルトの動作はのUIWebViewをクリアし、その結果、要求を殺すことは明らかであるということであったように見えます。私の実装を追加して何が起こっているのか調べるために、私はいくつかのコードを書いてエラーをビューに書き留めました.Duncanが指摘しているように、これが私のものです。

コールバックで-999エラーコードを無視するのはかなり恐ろしい解決策ですが、私はダクトテープで問題ありません。

これはUIWebViewの問題(Tweetie、Twitterifficなど)だったかどうかをテストするためにかなりのアプリを試してみましたが、すべて問題がありました。開発者にとってはこれがかなり一般的な見落としであるようです。多分、Appleは次のバージョンでこれをクリーンアップすることができます。

その他の興味深い点は、http://en.wikipedia.comの代わりにhttp://en.m.wikipedia.comを使用するようにURLを切り替えると、問題がなくなったという点です。

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

ここであなたの研究を行ったようです。確信している。私はあなたがアップルとレーダーを提出するならば、あなたが私たちに恩恵を全うしていると思います。テストアプリケーションを登録する際には必ずテストアプリケーションを含めるようにしてください。 –

+0

ありがとうございました。私はDuncanの作業を試してみましたが、実際にこの問題を回避しています。私はUIWebViewが間違っているように感じるが、それが動作する場合は... :) – RedBlueThing

+0

Tweete2の最新のバージョンは、バグについて@atebitsをtweeted修正:) – RedBlueThing

答えて

17

ここに答えがありますように見える:

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

今度はを参照:

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

あなたはWebViewの中にこのようなハックを必要とするようになっています。 didFailLoadWithError:デリゲート:

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

何が起こっているのかは、デリゲートがjavascriptまたはおそらくUIWebViewのバグでも発生する可能性のある「キャンセル」(-999)の失敗です。

あなたのコードでは、非常に同じUIWebViewを使用してエラーを表示しているため、webviewに何も表示されません。 NSLogを使用してエラーが発生した場合は、障害が発生しているはずですが、ページが正常にロードされたため、障害が偽であるというヒントが表示されます。

関連する問題