Поскольку ни один из этих ответов фактически не отвечает на вопрос, я собираюсь подробно рассказать о том, как я реализовал обновление токена OAuth с помощью SDK Facebook.
SDK автоматически обновит ваши токены, когда вы делаете запросы, однако, в моем сценарии мы отправляем токены на наши серверы, и нам нужно использовать последний токен. Поэтому, когда наш сервер показывает, что нам нужны новые токены, мы делаем следующее:
Примечание Вы можете передать AppID в FBSession
или добавить ключ FacebookAppID
в список приложений (это то, что мы делаем).
- (void)renewFacebookCredentials {
if (FBSession.activeSession.state == FBSessionStateOpen ||
FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
[self sessionStateChanged:[FBSession activeSession] state:[FBSession activeSession].state error:nil];
} else {
// Open a session showing the user the login UI
// You must ALWAYS ask for public_profile permissions when opening a session
[FBSession openActiveSessionWithReadPermissions:@[@"public_profile",@"email"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
//this block will run throughout the lifetime of the app.
[self sessionStateChanged:session state:state error:error];
}];
}
}
Вы можете использовать метод sessionStateChanged:
, который Facebook включает в свою документацию, но упрощенный обработчик выглядит следующим образом:
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error {
// If the session was opened successfully
NSString *accessToken;
if (!error && state == FBSessionStateOpen && [[session accessTokenData] accessToken]){
// Show the user the logged-in UI
//@see http://stackoverflow.com/questions/20623728/getting-username-and-profile-picture-from-facebook-ios-7
accessToken = [[session accessTokenData] accessToken];
//Now we have an access token, can send this to the server...
} else {
//No access token, show a dialog or something
}
//either call a delegate or a completion handler here with the accessToken
}
Имейте в виду, что некоторые вызовы API FBSession проверяют соответствие потоков, поэтому я обнаружил, что должен был обернуть все свои вызовы FBSession внутри dispatch_async(dispatch_get_main_queue(), ^{...