NSURLConnectionを非同期的に使用するとデータが返されない
-
16-09-2019 - |
質問
私はかなりの時間を過ごしています
単純ですが、仕事ができないようです。を構築しています
Web ホストからデータを取得する iPhone アプリ。私は。。をしようとしています
を維持したいので、ホストへの非同期接続を確立します。
接続中にデバイスが解放されました。(sendSynchronousRequest がフリーズする
リクエストが完了するまで電話をかけ続けます。)私の接続コードは次のとおりです。
//temp url to see if data is returned:
NSURL *theURL = [NSURL URLWithString:@"http://www.theappleblog.com/feed"];
NSURLRequest *dataRequest = [NSURLRequest requestWithURL:theURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
/* establish the connection */
theConnection = [[NSURLConnection alloc]
initWithRequest:dataRequest
delegate:self
startImmediately:YES];
if (theConnection == nil) {
NSLog(@"Connection Failure!");
self.urlData = nil;
} else {
self.urlData = [[NSMutableData data] retain];
}
適切なデリゲート メソッドをすべて設定しました。
-(void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse*)response
{
[urlData setLength:0];
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = YES;
NSLog(@"Received Response!");
}
-(void)connection:(NSURLConnection *)connection
didReceiveData:(NSData*)incrementalData
{
[self.urlData appendData:incrementalData];
NSNumber *resourceLength = [NSNumber
numberWithUnsignedInteger:[self.urlData length]];
NSLog(@"resourceData length: %d", [resourceLength intValue]);
NSLog(@"filesize: %d", self.urlDataSize);
NSLog(@"float filesize: %f", [self.urlDataSize floatValue]);
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(@"Connection finished loading\n");
NSLog(@"Succeeded! Received %d bytes of data",[urlData length]);
_isFinished = YES;
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = NO;
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
NSLog(@"Error: %@",[error localizedDescription]);
}
ご覧のとおり、私は大量のログ メッセージを取得しました。
かどうかを確認する 何でも 全然伝わってきてた。私の接続テスト
TRUE として返されますが、データはロードされません。さっきも言ったように、確かに
私は何かをしている(またはしていない)に違いありません 本当に バカ。でも何?
ご協力をいただければ幸いです。
ありがとう、ローレンス
解決
これは直接あなたの質問に答えていませんが、あなたはベンCopseyの<のhref =「http://allseeing-i.com/ASIHTTPRequest-CFNetwork-wrapper-for-HTTP-requests」のrelに探して検討するかもしれません=」 ASIHTTPRequest
クラスをラップし、適切にこれを行うの外に多くの作業を要する非同期、スレッドの要求コードを含んのライブラリ、noreferrer nofollowを "> CFNetwork
ます。
他のヒント
問題は、私はプログラムの流れを継続してダウンロードを完了するの接続を許可するように停止していなかったということでした。提案のすべてをありがとうございました。
いくつかの提案:
最初のスニペットでは、代わりに
theConnection
に割り当ててみてくださいself.theConnection
プロパティ アクセサー メソッドが呼び出されることを確認します。色々な場所で交流もしますself.urlData
そしてurlData
. 。を実行して、それらをすべて一貫性を持たせたい場合がありますself
.を作りたいかもしれません。
dataRequest
プロパティも同様に通過しますself
確実に保持されるようにするためです。self.urlData = [[NSMutableData data] retain];
-- 余分な保持は必要ありません。を通過するself
あなたのためにそれをします。余分な保持により、すべてが完了した後でもオブジェクトがくっついて漏れてしまいます。これに関連して、NSLogs では各オブジェクトの保持数を必ず出力してください。また、これらの構造 (またはセット) を解放するための一般的なクリーンアップ ルーチンを用意しておくとよいでしょう。
self.foo = nil
)そのため、問題が発生した場合はいつでもルーチンを呼び出して問題を解決できます。Charles または WireShark のコピーを取得し (またはコンソールで tcpdump を実行し)、ネットワーク トラフィックを監視します。フローのどの段階で失敗しているかを正確に特定するのに役立ちます。
最初の考え - このすべてのコードを含むオブジェクトは適切に保持されていますか?解放されているため、接続の割り当てが解除されている可能性があります...
それ以外の場合は、少なくとも応答が表示されるはずです。
明らかに間違ったところは何もありません。実質的に同じコードがあり、正常に動作します。私が見た唯一の違いは次のとおりです。
の代わりに NSURLRequestUseProtocolCachePolicy を使用しています。 NSURLRequestReloadIgnoringLocalCacheData
connection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; を使用します。startImmediately を指定する代わりに:はい (デフォルトなので)
デリゲート メソッドが存在する場合、どのメソッドが呼び出されているかを知ると役立ちます。少なくとも、connectionDidFinishLoading または connectionDidFail の少なくとも一方を呼び出す必要があります。そうでない場合は、デリゲートの設定に何か問題がある可能性があります。デリゲート メソッドの署名が正しいこと、および正しい項目をデリゲートとして渡していることを絶対に確信していますか?
それはのNSLog文のいずれかが実行される場合は、あなたの質問から明らかではないので、何をゼロするのは難しいです。あなたが取得している結果について、もう少し明確にしてください。
簡単に見てから、潜在的な問題のように見える唯一のものは、あなたが接続を設定するときに競合状態を持っているということです。 didReceiveData:self.urlDataが割り当てられたの前に呼び出されますネットワークが特に速いと-connectionがいることをスリムしかし、ゼロ以外のチャンスがあります。 didReceiveResponse::私はどちらかの接続を開始する前に、または-connectionでurlDataを割り当てることをお勧めしたい。これを防ぐために、
それはそれを修正しない場合は、は、あなたからより多くの情報が必要とされます。
あなたは、このコードは、非同期メソッドを使用して正常に動作しますと言いますか?そのURLのテスト、それは別のものにリダイレクトするので、何をリダイレクトデリゲートメソッドを実装する場合は?あなたは、いくつかの異なるURLをしよう?
それ以外の応答アプリですか?実行ループは実行されていますか?アプリは、要求を開始した後に何をするのか - それは戻って実行ループにそのイベントハンドラから復帰しますか? (そうでない場合、彼らは実行ループを介して配信しているので、あなたは、あなたのコールバックのいずれかを得ることは決してないだろう。)
NSURLConnectionは、プロトコルの任意のタイプだけでなく、HTTPで動作するように設計されています。 didFail:withErrorは、の接続のエラーのためではなく、のプロトコルのエラーのために呼ばれているこれは、接続することを意味します。あなたは、プロトコルエラーをチェックしていない - あなたが接続してそれらをキャッチする必要があります。didReceiveResponseを:.トリックは、渡された応答オブジェクトが実際にNSHTTPURLResponseオブジェクトであるということです。あなたは、応答のからstatusCodeをチェックすると、私はあなたが404またはサーバ500のようなHTTPエラーを取得していると思うわ。