AWS SDK iOSのS3アップロード部分についてコードを読む
はじめに
OSSであるAWS SDK iOSのS3アップロード部分についてコードを読む
AWS S3 SDK登場人物
- タスクに関わるBoltsから移行されたやつら
- AWSTask<__covariant ResultType> : NSObject
- Future/Promise的なやつ
- async/awaitのawaitもできる
- AWSExecutor : NSObject
- クロージャを実行するやつ
- Grand Central Dispatcherをラップしたようなイメージ
- AWSCancellationToken : NSObject
- キャンセルするやつ
- 作成し、
- AWSTask<__covariant ResultType> : NSObject
- アップロードに関するやつ
- AWSS3TransferUtilityUploadTask : AWSS3TransferUtilityTask
- completionHandlerやprogressHandlerをセットできる
- AWSTaskからできるのでこれを直接やらなくてもいい
- completionHandlerやprogressHandlerをセットできる
- AWSS3TransferUtilityTask: NSObject
- こいつのデータを永続化したら良さそう
- 永続化必須
- NSString *transferID;
- その他 AWSS3TransferUtilityTask ができること
- キャンセル
- completionHandlerやprogressHandler
- AWSS3TransferUtilityUploadTask : AWSS3TransferUtilityTask
interceptApplication
- バックグランド通信成功時にアプリがバックグラウンドから復帰させられるための処理
- 復帰してファイル出力したりDB書き込みしたりする
- 復帰させられるというのはオンメモリ上では生きてる(=終了してるわけじゃない)
- そもそも終了してたらバックグラウンド通信も終了している
- 復帰させられるというのはオンメモリ上では生きてる(=終了してるわけじゃない)
- 復帰してファイル出力したりDB書き込みしたりする
何をやってるの?
- idが渡されるのでそのidを持ってるかチェック
- completionHandlerを保持
+ (void)interceptApplication:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)(void))completionHandler {
AWSDDLogDebug(@"interceptApplication called for URLSession [%@]", identifier);
// For the default service client
if ([identifier isEqualToString:_defaultS3TransferUtility.sessionIdentifier]) {
_defaultS3TransferUtility.backgroundURLSessionCompletionHandler = completionHandler;
}
// For the SDK managed service clients
for (NSString *key in [_serviceClients allKeys]) {
AWSS3TransferUtility *transferUtility = [_serviceClients objectForKey:key];
if ([identifier isEqualToString:transferUtility.sessionIdentifier]) {
AWSDDLogDebug(@"Setting completion handler for urlSession [%@]", identifier);
transferUtility.backgroundURLSessionCompletionHandler = completionHandler;
}
}
}
ここでは保持してるだけだが、このcompletionHandlerを終了した際に呼び出すとNSURLSessionのDelegateが動作するらしい。
(記述はバックグラウンドダウンロードなのでDelegateはダウンロードの urlSessionDidFinishEvents(forBackgroundURLSession:)
が動作してる)
When all events have been delivered, the system calls the urlSessionDidFinishEvents(forBackgroundURLSession:) method of URLSessionDelegate. At this point, fetch the backgroundCompletionHandler stored by the app delegate in Listing 3 and execute it. Listing 4 shows this process.
Note that because urlSessionDidFinishEvents(forBackgroundURLSession:) may be called on a secondary queue, it needs to explicitly execute the handler (which was received from a UIKit method) on the main queue.
つまり、このcompletionHandlerはアプリ内のDelegateに終了を通知するため。なぜそうやるのか想像するに
- バックグラウンド通信の終了はAppDelegateに通知
- AppDelegateからアプリ内のNSURLSesssionに通知する手段としてcompletionHandlerを使う
ということだろう(想像です)。