iOSのネットワークキャッシュ。 はじめに

ほとんどすべてのモバイルアプリケーションがネットワークからデータを受信します。

残念ながら、ネットワークへのアクセスは常に可能とは限らないため、開発者がアプリケーションにネットワークキャッシュを正しく実装することが重要です。



この点で、キャッシュを実装する方法と、それらをいつ適用するかについての一連の記事を書くことにしました。



だから、はじめに。





キャッシングの戦略



キャッシングには、オンデマンドキャッシングとプリキャッシングの2つのアプローチがあります。



オンデマンドキャッシュにより、以前に表示されたコンテンツをオフラインで表示できます。 サーバーから受信したデータはデバイスに保存され、リクエストごとにその関連性がチェックされます。 データが関連する場合は、ディスクから取得され、関連しない場合は、リクエストがサーバーに送信されます。



事前キャッシュは、ユーザーが必要とする可能性のあるすべてのデータが受信され、すぐにディスクに保存されることを意味します。



使用するキャッシング戦略を決定するには、ダウンロード後にデータの後処理が必要かどうかを理解する必要があります。 後処理は、ダウンロードされたデータの変更を意味します。 たとえば、HTMLページのリンクを変更して、ローカルにキャッシュされた画像を指すようにするなど。



キャッシュを保存する場所



アプリケーションは、サンドボックスにのみ情報を保存できます。 キャッシュされたデータはユーザーによって生成されないため、NSDocumentsDirectoryではなくNSCachesDirectoryに保存する必要があります。 すべてのキャッシュデータ用に個別のディレクトリを作成することをお勧めします。



この例では、MyAppCacheディレクトリがLibrary / Cachesフォルダーに作成されます。

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *cachesDirectory = [paths objectAtIndex:0]; cachesDirectory = [cachesDirectory stringByAppendingPathComponent:@”MyAppCache”];
      
      





Library / Cachesフォルダーにキャッシュを保存する理由は、iCloud(およびiTunes)がこのディレクトリをバックアップから除外するためです。 したがって、iCloudの限られたスペース(現在は無料アカウントの場合、これは約5 GBです)が不要なデータの保存に費やされていません。



アプリケーションで集中的なキャッシングが発生する場合は、ディスクの代わりにメモリを使用し、アプリケーションが閉じられたときにディスクにデータをアップロードすることをお勧めします。 これは、iPhoneのフラッシュメモリの書き込み/読み取りサイクル数が制限されており、もう一度ロードすることは望ましくないためです。



キャッシュを保存する方法



iOSには、ユーザーデータを保存するさまざまな方法があります。 キャッシュに最適:NSKeyedArchiver、Core Data、SQLite、NSURLCache。



NSKeyedArchiver



データモデルのキャッシュは、NSKeyedArchiverクラスを使用して実装されます。 モデルオブジェクトをアーカイブするには、モデルクラスがNSCodingプロトコルを実装する必要があります。 すなわち、メソッド

 - (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder;
      
      





クラスがNSCodingを実装している場合、アーカイブするには、次のいずれかのメソッドを呼び出すだけで十分です。

 [NSKeyedArchiver archiveRootObject:objectForArchiving toFile:archiveFilePath];
      
      





 [NSKeyedArchiver archivedDataWithRootObject:objectForArchiving];
      
      





最初の方法は、パスarchiveFilePathに沿ってアーカイブファイルを作成します。 2番目のメソッドはNSDataオブジェクトを返します。 NSDataは、ファイルにアクセスするための追加費用がないため、通常は高速ですが、データはアプリケーションのメモリに保存されます。



ファイル(またはNSDataへのポインター)からモデルを解凍するには、NSKeyedUnarchiverクラスを使用します。 次のいずれかの方法を使用してデータを解凍します。

 [NSKeyedUnarchiver unarchiveObjectWithData:data];
      
      





 [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
      
      





NSKeyedArchiver / NSKeyedUnarchiverを使用するには、モデルがNSCodingプロトコルに準拠している必要があります。 NSCodingの実装は非常に簡単ですが、多くのファイルがある場合は時間がかかります。 したがって、このプロセスを自動化するには、何らかのツールを使用することをお勧めします。 たとえば、 AppCode開発環境



コアデータ



Core Dataにデータを保存するには、エンティティの説明(エンティティ)、およびエンティティ間の関係(関係)を含むモデルファイルを作成し、データを保存および取得するためのメソッドを記述する必要があります。 Core Dataを使用すると、標準のメールおよびカレンダーアプリケーションで行われているように、実際のオフラインアプリケーションモードを取得できます。



事前キャッシュを実装する場合、不要なデータを定期的に削除する必要があります。 そうしないと、キャッシュサイズが著しく大きくなり始め、パフォーマンスが低下します。 ローカルの変更は、一連の変更を追跡してサーバーに送り返すことで同期されます。 変更セットを追跡するための多くのアルゴリズムがありますが、Gitで機能するものを使用するのが最善です。



コアデータはオンデマンドキャッシュに使用できますが、使用しないことをお勧めします。 Core Dataの主な利点は、すべてのデータを解凍せずにモデルのプロパティにアクセスできることです。 ただし、アプリケーションにコアデータを実装する複雑さは、この利点を無効にします。



生のSQLite



SQLiteを使用するには、アプリケーションをlibsqlite3ライブラリにリンクする必要がありますが、このアプローチには重大な欠点があります。

すべてのsqlite3ライブラリとオブジェクトリレーショナルマッピング(ORM)エンジンは、コアデータよりも低速です。 さらに、iOSでのsqlite3の実装はスレッドセーフではありません。 したがって、個別にコンパイルされたsqlite3ライブラリ(スレッドセーフフラグでコンパイルされた)を使用していない場合は、sqlite3データベースへのスレッドセーフな読み取り/書き込みアクセスを確保する責任はユーザー自身にあります。



Core Dataはより多くの機能(データの移行、組み込みのスレッドセーフなど)を提供できるため、iOSでネイティブSQLiteを使用しないことをお勧めします。



NSURLCache



オンデマンドのキャッシングに最適です。 NSURLRequestによって返されるデータをほぼ自動モードでキャッシュでき、最小限のコードが必要です。



わずか数行で、アプリケーションはリクエスト用のディスクキャッシュを受け取ります。

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil]; [NSURLCache setSharedURLCache:URLCache]; }
      
      







残念ながら、RESTサービスにのみ適しているため、一部のHTTPヘッダーを操作する際に問題があります。



おわりに



オンデマンドキャッシュを実装するには、NSURLCacheまたはNSKeyedArchiverを使用することをお勧めします。 完全なオフラインモードを実装するには、CoreDataを操作する必要があります。



次のパートでは、NSURLCache / NSKeyedArchiverの動作を詳細に検討し、適切なケースについて説明する予定です。



All Articles