リモート呼び出しをバックエンドに集中するためのクラスを作成しています。 コールはoauthで認証されなければならないので、各メソッドで、まず自分のトークンがvalideかどうかをチェックし、そうでなければリフレッシュするように要求します。並行メソッドの実行とブロックを防止する
それぞれの方法には、次のようになります方法
checkOAuthTokenAndRunは、トークンの有効性を確認し、必要に応じて新しいものを要求します。 私が問題になっているのは、checkOAuthTokenAndRunが同時に呼び出されないようにして、リフレッシュされている(書き込まれている)ときに資格情報を読み取らないようにすることです。
私はNSLockを試みたが、ブロック(マルチスレッド)で、私は次のエラーを取得する:あなたが見ての通り、
- (void)checkOAuthTokenAndRun:(void (^)())action orFail:(nullable void(^)(AFHTTPRequestOperation * __nullable operation, NSError * __nullable error))failure
{
NSLog(@"lock oauth check/refresh");
[oauthLock lock];
if (credential == nil || [credential isExpired])
{
NSLog(@"Credentials are null or expired");
if (credential == nil || credential.refreshToken == nil)
{
NSLog(@"Credentials are null or anonymous+expired");
[self getAnonymousCredentialsAndRun:^{
NSLog(@"unlock oauth");
[oauthLock unlock];
action();
} orFail:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nullable error) {
NSLog(@"unlock oauth");
[oauthLock unlock];
failure(operation, error);
}];
}
else
{
NSLog(@"Credentials are expired");
AFOAuth2Manager *OAuth2Manager = [[AFOAuth2Manager alloc] initWithBaseURL:[NSURL URLWithString:BaseURL] clientID:clientId secret:clientSecret];
[OAuth2Manager authenticateUsingOAuthWithURLString:@"/oauth/v2/token" refreshToken:credential.refreshToken success:^(AFOAuthCredential *_credential) {
credential = _credential;
NSLog(@"Received refreshed token");
[AFOAuthCredential storeCredential:credential
withIdentifier:OAuthProviderIdentifier];
NSLog(@"unlock oauth");
[oauthLock unlock];
action();
} failure:^(NSError *error) {
NSLog(@"Failed refreshing oauth token (%@)", [error localizedDescription]);
// remove refresh token
NSLog(@"Unable to get oauth token, delete credentials (%@)", [error localizedDescription]);
[AFOAuthCredential deleteCredentialWithIdentifier:OAuthProviderIdentifier];
credential = nil; //[AFOAuthCredential retrieveCredentialWithIdentifier:OAuthProviderIdentifier];
NSLog(@"unlock oauth");
[oauthLock unlock];
failure(nil, error);
}];
}
}
else { // run the action
NSLog(@"Credentials are valid (%@)", (credential.refreshToken.length ? @"refresh token defined" : @"refresh token not defined"));
NSLog(@"unlock oauth");
[oauthLock unlock];
action();
}
}
私が使用しています:ここで
*** -[NSLock lock]: deadlock (<NSLock: 0x7ffd9313d9b0> '(null)')
は、完全なcheckOAuthTokenAndRun方法でありますこれがデッドロックを取得する理由であるかどうかはわかりません。
はもう一度、私はあなたの助けを
おかげ
約束をチェックしてください。基本的な考え方は、トークンを検証することが約束になることです。他のすべての要求は、それが達成されると、複数回実行されないその約束を断ち切ります。セッション中にトークンを無効にすることができる場合は、約束を無効にする方法を考え出す必要があります。私は現在の図書館にこれのための施設がないと確信していません。 (1つの実装として、FBからのBoltsフレームワークを参照してください) – Avi
@Aviありがとう、PromiseKitを試してみましたが、音は良いですが、トークンメソッドの同時アクセスをロックすることはできません... – liilo