Ничто из того, что я читаю (много статей о разработчиках FB и SO-вопрос), не помогает, поэтому я решил опубликовать здесь. Я пытаюсь заставить все это работать с iOS 6 и Facebook SDK 3.1.1.
У меня довольно простая настройка: мое приложение для iOS аутентифицируется в Facebook, я передаю access_token на свой сервер, и теперь пользователь входит в мое приложение. Единственная другая вещь, которую они могут сделать, связанная с Facebook, — это опубликовать что-нибудь на своей стене. Я использую устаревшее диалоговое окно, чтобы пользователь мог добавлять свои собственные комментарии.
Все работает отлично на новой установке в течение первого часа или около того. Если пользователь вошел в систему через приложение «Настройки iOS», ему предоставляется окно быстрого подтверждения iOS, я получаю его токен, отправляю его на свой сервер, и все в порядке.
Если я вставлю полученный токен в отладчик токенов доступа Facebook, он покажет, что срок его действия истечет через час.
Если я подожду этот час и вернусь в приложение после этого, все, что я попытаюсь сделать, выдаст мне эту ошибку:
{"error_code":190,"
error_msg":"Error validating access token:
Session has expired at unix time 1351497600.
The current unix time is 1351525180. }
- Что мне нужно сделать, чтобы все просто работало? я читал, что в SDK 3.1.1 FBSession просто позаботится об этом, но это не похоже на тот случай. Срок действия моего токена доступа истекает, и когда это произойдет, iOS/FB SDK не вернет мне обновленный.
- Даже выход из системы (который вызывает
[FBSession.activeSession closeAndClearTokenInformation]
) не решает этого. Единственное, что я смог сделать, это «Сбросить содержимое и настройки» в настройках симулятора iOS, повторно ввести свои учетные данные FB в Settings.app и перестроить мое приложение. Только тогда я смогу получить еще один токен, срок действия которого истекает через час.
Случайные заметки:
- Когда мое приложение возобновляет работу, я звоню
[FBSession.activeSession handleDidBecomeActive]
и[self.facebook extendAccessTokenIfNeeded]
. - Согласно вопросу SO, указанному выше, SDK должен автоматически вызывать
FBSession#renewSystemAuthorization
. Я поместил туда NSLog и никогда не видел, чтобы этот метод вызывался.
ОБНОВЛЕНИЕ №1:
Я упомянул, что читал, что SDK будет обрабатывать недействительные токены или токены с истекшим сроком действия. Похоже, это должно произойти в FBRequestConnection#completeWithResults:orError:. См. встроенные комментарии для заметок о пути кода.
- (void)completeWithResults:(NSArray *)results
orError:(NSError *)error
{
int count = [self.requests count];
for (int i = 0; i < count; i++) {
FBRequestMetadata *metadata = [self.requests objectAtIndex:i];
id result = error ? nil : [results objectAtIndex:i];
NSError *itemError = error ? error : [self errorFromResult:result];
id body = nil;
if (!itemError && [result isKindOfClass:[NSDictionary class]]) {
NSDictionary *resultDictionary = (NSDictionary *)result;
body = [FBGraphObject graphObjectWrappingDictionary:[resultDictionary objectForKey:@"body"]];
}
...
// *******************************************
// My code actually falls into this block, proving that I do in fact have an invalid session
// *******************************************
if ([self isInvalidSessionError:itemError
resultIndex:error == itemError ? i : 0]) {
[metadata.request.session closeAndClearTokenInformation:itemError];
// *******************************************
// Unfortunately metadata.request.session is nil, so this condition is never
// run, so renewySystemAuthorization is never called
// *******************************************
if (metadata.request.session.loginType == FBSessionLoginTypeSystemAccount){
[FBSession renewSystemAuthorization];
}
}
...
}