(iOS)サーバーから取得した情報をローカルにキャッシュしておき、オフラインの時はキャッシュ情報を参照する
この記事の追加ネタです。
iOSで自作WebAPIにアクセスする - おかひろの雑記
外出先からスマホやタブレットでサーバーにアクセスしようとしても、3GやLTE回線が繋がらなかったり、
繋がったとしても社内システムに接続する場合はVPN接続が必要だったりと、
情報を見ようとしてもオフラインだから見られないというケースも結構あると思います。
なので、一度アクセスした情報はローカルにキャッシュしておき、オンラインであればサーバーから最新の情報を取得してキャッシュに保存、
オフラインの場合はキャッシュがあればその情報を表示・・・という実装を考えてみました。
サーバーから取得してローカルにキャッシュするデータは、下記2パターンを考えます。
- テキストデータ(JSON)
- ファイル(PDF,JPG,Word,Excel,PowerPointなど。UIWebViewで開く。)
JSONデータの場合
ローカルへの保存はSQLiteでもいいですが、NSUserDefaultsで十分だと思います。
NSArrayやNSDictionaryを保存することもできますが、要素が複雑だとダメな場合もあるみたいなので、
サーバーから取得したNSDataをNSUserDefaultsに保存し、読みだすときにJSON変換するようにします。
[SVProgressHUD show]; NSString *url = [NSString stringWithFormat:@"http://sample.example.com/webapi/test"]; [AsyncURLConnection request:url completeBlock:^(NSData *data){ NSError *jsonError = nil; self.dataArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; if(!self.dataArray) { NSLog(@"Error : %@",jsonError); UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"エラー" message:@"JSONエラー" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; [SVProgressHUD dismiss]; return ; } // UserDefaultsに値を保存 [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"testDataArray"]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ dispatch_async(dispatch_get_main_queue(),^{ // 処理 ... [SVProgressHUD dismiss]; }); }); } errorBlock:^(NSError *error){ NSError *jsonError = nil; NSData *udData = [[NSUserDefaults standardUserDefaults] dataForKey:@"testDataArray"]; if(udData) { self.dataArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; // 処理 ... } else { NSLog(@"%@",error); UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"エラー" message:@"ネットワークエラー" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } [SVProgressHUD dismiss]; }];
ファイルの場合
ファイルはUIWebViewで開くのが簡単だと思います。
まずはサーバーにアクセスし、ファイルを取得できたらローカルに保存します。
UIWebViewは、ローカルに保存したファイルを常に開くようにします。
ローカルに保存するときのファイルの拡張子は注意が必要で、これがないとUIWebViewが正しく認識してくれません。
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://sample.example.com/webapi/testfile.pdf"]]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; // ローカルに保存するファイルパス NSString *fileName = [dictionary objectForKey:@"testfile.pdf"]; NSString *filePath = [NSString stringWithFormat:@"%@/%@", [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"], fileName]; NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; if(error) { NSLog(@"Error."); } else { // ローカルに保存 NSFileManager *fileManager = [NSFileManager defaultManager]; [fileManager createFileAtPath:filePath contents:[NSData data] attributes:nil]; NSFileHandle *file = [[NSFileHandle fileHandleForWritingAtPath:filePath] retain]; [file writeData:data]; } // URLエンコード filePath = [filePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURLRequest *webViewRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:filePath]]; // WebViewで開く [viewController.webView loadRequest:webViewRequest];