非アクティブ状態が何時間も続くと、アプリは正常な API 呼び出しを取得しません。
動作を再現する手順:
- Amazon Cognito ID の作成。
- API 呼び出し。
- アプリをバックグラウンドに置きます。
- 8 時間後にコードを更新します。(後述の initializeAmazonCongnitoProviderWithCompletionBlock は、アプリが 8 時間後にのみフォアグラウンドになるときに最初に呼び出されます) 不足している認証トークンは、スクリーンショットに示されているように表示されます。どの AWS サービスが影響を受けますか?
- (void)initializeAmazonCognitoProviderWithCompletionBlock:(void (^)(void))completion { [[UIApplication sharedApplication].keyWindow setUserInteractionEnabled:FALSE]; NSString* AWSCognitoPoolID = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"AWSCognitoID"]; AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AMAZON_COGNITO_REGION identityPoolId:AWSCognitoPoolID]; [credentialsProvider clearCredentials]; AWSServiceConfiguration *configuration =[[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider]; AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration; [self getCognitoID:credentialsProvider CompletionBlock:^{ [self expirationHandler:credentialsProvider CompletionBlock:^{ dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication].keyWindow setUserInteractionEnabled:TRUE]; }); completion(); }]; }]; } - (void)expirationHandler:(AWSCognitoCredentialsProvider *)creds CompletionBlock: (void (^)(void))completion { [[creds credentials] continueWithBlock:^id(AWSTask *task) { if (task.error) { [self initializeAmazonCognitoProviderWithCompletionBlock:^{}]; } else { AWSCredentials *cred = (AWSCredentials*) task.result; NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; /* https://aws.amazon.com/premiumsupport/knowledge-center/security-token-expired/ https://forums.aws.amazon.com/thread.jspa?threadID=166398 We should fire timer before 5 minutes of expiration. NSString *expF = [dateFormat stringFromDate:cred.expiration]; */ [NSTimer scheduledTimerWithTimeInterval:cred.expiration.timeIntervalSinceNow - 300 target:self selector:@selector(initializeAmazonCognitoProviderWithCompletionBlock:) userInfo:nil repeats:NO]; completion(); } return nil; }]; } - (void)getCognitoID:(AWSCognitoCredentialsProvider *)creds CompletionBlock: (void (^)(void))completion { [[creds getIdentityId] continueWithBlock:^id(AWSTask *task) { if (task.error) { NSLog(@"Error: %@", task.error); [self initializeAmazonCognitoProviderWithCompletionBlock:^{}]; } else { NSString *cognitoId = task.result; NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults]; if (![[standardDefaults valueForKey:@"UserCognitoID"] isEqualToString:cognitoId]) { [standardDefaults setObject:@"" forKey:BainPreferenceToken]; [standardDefaults setInteger:0 forKey:@"registrationPostComplete"]; } [standardDefaults setObject:cognitoId forKey:@"UserCognitoID"]; [standardDefaults synchronize]; completion(); } return nil; }]; }