AmazonS3とiOS間でファイルをやりとりする(その2)
前回 - AmazonS3とiOS間でファイルをやりとりする(その1) - assaulter's diary
の続きになります。僕はこういう感じで実装しました。
ダウンロード
仕様 : ユーザーにはDLの結果のみを見せる(今回はStringを返す)。データはよしなに扱う。
Clientを作成
メンバで保持。初期化時に鍵が必要。また、リージョンを設定しておく(やらない場合はデフォルトが入ったはず)。
- (id)init { if (self = [super init]) { _client = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY]; _client.endpoint = [AmazonEndpoints s3Endpoint:AP_NORTHEAST_1]; } return self; }
ダウンロードapi
/// 公開する関数 - (void)downloadDataWithCompletion:(void(^)(NSString* message))resultBlock { [self getDataWithCompletion:^(S3GetObjectResponse *response) { /// response.bodyに格納されているので、よしなにやる if (response.bodyを使ってよしなにやった結果) { resultBlock(@"DL成功"); } else { resultBlock(NSLocalizedString(@"保存失敗"); } } errorBlock:^(NSError *error) { resultBlock(error.userInfo[@"NSLocalizedDescription"]); }]; } /// ヘルパ関数 - (void)getDataWithCompletion:(void(^)(S3GetObjectResponse* response))responseBlock errorBlock:(void(^)(NSError* error))errorBlock { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ S3GetObjectRequest* getRequest = [[S3GetObjectRequest alloc] initWithKey:@"オブジェクトの名前" withBucket:@"バケット名"]; getRequest.contentType = CONTENT_TYPE; S3GetObjectResponse* getResponse = [self.client getObject:getRequest]; /// ここからmain threadで処理される(非同期) dispatch_async(dispatch_get_main_queue(), ^{ if (getResponse.error) { errorBlock(getResponse.error); } else { responseBlock(getResponse); } }); }); }
通信してレスポンスを取ってくるところの非同期処理はGCDを使いました。
参考 - 8.2 Grand Central Dispatch · mixi-inc/iOSTraining Wiki · GitHub
ネストはちょい深くなるけど、mainスレッドに非同期で返す部分をわざわざperformSelectorOnMainThreadでやると関数書かないといけないので、block返すだけとかそういう場合はこっちの方がスッキリするかな。
アップロード
あんま変わりませんね。clientは既に用意されている前提で、ユーザーには結果しか返しません。
/// 公開する関数 - (void)uploadDataWithCompletion:(void(^)(NSString* message))resultBlock { [self putDataWithResponseBlock:^(S3PutObjectResponse *response) { resultBlock(@"uploadに成功した"); } errorBlock:^(NSError *error) { resultBlock(error.userInfo[@"NSLocalizedDescription"]); }]; } /// ヘルパー - (void)putDataWithResponseBlock:(void(^)(S3PutObjectResponse* response))responseBlock errorBlock:(void(^)(NSError* error))errorBlock { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ S3PutObjectRequest* putRequest = [[S3PutObjectRequest alloc] initWithKey:@"オブジェクト名" inBucket:@"バケット名"]; putRequest.contentType = CONTENT_TYPE; putRequest.data = 適当なメソッドでデータを取ってくる; S3PutObjectResponse* putResponse = [self.client putObject:putRequest]; dispatch_async(dispatch_get_main_queue(), ^{ // ここからはmainThreadで実行される if (putResponse.error) { errorBlock(putResponse.error); } else { responseBlock(putResponse); } }); }); }