2012-03-23 6 views
0

私のアプリのdidFinishLaunchingWithOptionsでファイルを取得してアプリケーションディレクトリに保存する機能を現在使用しています。リモートファイルを取得するときに接続が遅いためにアプリがクラッシュしないようにする

弱い接続があると、アプリがクラッシュすることがあります。私は、アプリケーションをクラッシュさせる前にAppleが許す20秒の時間制限があることを読んだ。これは正しいです?もしそうなら、非常に弱い接続をしていることを除いて、アプリケーションが完璧に動作するので、これは私の問題を引き起こしていると私は信じています。

どうすればこの問題を解決し、これを補うためにロジックを変更できますか?

- (void)writeJsonToFile 
{ 
//applications Documents dirctory path 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 

//live json data url 
NSString *stringURL = @"http://link-to-my-data.json"; 
NSURL *url = [NSURL URLWithString:stringURL]; 
NSData *urlData = [NSData dataWithContentsOfURL:url]; 

//attempt to download live data 
if (urlData) 
{ 
    NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"data.json"]; 
    [urlData writeToFile:filePath atomically:YES]; 
} 
//copy data from initial package into the applications Documents folder 
else 
{ 
    //file to write to 
    NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"data.json"]; 

    //file to copy from 
    NSString *json = [ [NSBundle mainBundle] pathForResource:@"data" ofType:@"json" inDirectory:@"html/data" ]; 
    NSData *jsonData = [NSData dataWithContentsOfFile:json options:kNilOptions error:nil]; 

    //write file to device 
    [jsonData writeToFile:filePath atomically:YES]; 
} 

}

答えて

5

これは、メインスレッド上でこの種のものを実行するために非常に悪い考えです:私はあなたがいると仮定 - あなたがネットワーク操作を待っている間、基本的に、あなたは全体のUIをブロックしますコンプリート。

dataWithContentsOfURLは、この種のものには適していません。 NSURLConnectionまたはAFNetworkingのようなラッパーライブラリーの1つを使用する方がはるかに優れています。これは、接続が正常に終了するようなケースを処理できるためです。

これらのライブラリには、データを非同期にダウンロードするための組み込みメソッドがあり、メインUIスレッドがロックされないようにします。

+0

私のスレッドの使用の欠陥を指摘してくれてありがとう。これは私の最初のアプリですので、私はまだスレッドとメモリ管理のコンセプトに合わせて調整しています。このメソッドの現在の実装を再考した後、私は、アプリケーションが起動した後、バックグラウンドでデータを更新するつもりです。あなたの答えは@SVGregと似ていましたが、最初に提案をして答えが得られました。 –

1

ダウンロードしたデータはいつ必要ですか?

答えによっては、スレッド内でメソッドを呼び出すことができます。これにより、メインスレッドがブロックされなくなります。

最初からデータが必要な場合でも、ローダーを作成してバックグラウンドでファイルをダウンロードしてから、ファイルをダウンロードした後にアプリをアクティブにすることができます。

+0

私のアプリでは、実行する前にデータが存在する必要があります。私はバンドル内のデータファイルのローカルコピーでアプリケーションを出荷していますので、最初にローカルデータを使用して、バックグラウンドで更新を取得します。私は新鮮なデータを待っている間、私は非アクティブな状態でアプリを残す必要がないので、これは最善のアプローチのようです。 –

+0

これは良い解決策として聞こえます。しかし、lxtとSVGregが書いたように、あなたがファイルをダウンロードするための最良の方法を見直してください。別の解決策は、ASIHTTPRequestを使用することですが、これは非常に大きなサイズではないと思うファイルをダウンロードするだけでは圧倒的かもしれません。 – o15a3d4l11s2

1

私はNSData *urlData = [NSData dataWithContentsOfURL:url];の内部実装からより独立していると思いますが、NSURLConnectionに基づいて独自のダウンロードクラスを実装する必要があります。

リンクを読むには:

URL Loading System Programming Guide

NSURLConnection Class Reference

NSURLConnectionDelegate Protocol Reference

はつまり、あなたのコードですべての接続エラーをキャッチし、この場合、右の動作を実装することができます。

+0

+1は、提案とサポートのリンクです。私が評価し、これが進めたいルートかどうかを判断します。 –

関連する問題