我的应用程序仅适用于 iOS7,为了避免麻烦,我决定不使用 Facebook SDK 进行身份验证,而是依赖 iOS 的 ACAccountStore。不幸的是,我仍然感到头疼。
我有一个名为 FacebookService 的类,其中一个方法名为login
. 我将在下面发布代码,但总的来说,我会按照标准的方式配置一个实例,ACAccountStore
然后调用requestAccessToAccountsWithType
. 在完成块中,如果granted
返回 false,则向用户发送消息并短路。
如果granted
是真的,那么我的代码用来假设我拥有使用以下代码获取用户的 oauthToken 所需的一切:
ACAccount *fbAccount = [[accountStore accountsWithAccountType:fbAccountType] lastObject];
ACAccountCredential *fbCredential = [fbAccount credential];
NSString *accessToken = [fbCredential oauthToken];
我oauthToken
从 中得到ACAccount#credential
,第一件奇怪的事情是根据文档:
出于隐私原因,此属性(在保存帐户后无法访问。
我可以肯定地告诉你,在大多数情况下,这个属性是绝对可以访问的,我可以使用它发送到我的服务器以查找以前经过身份验证的用户。
然而,少数时候,该值实际上是空的。在发生这种情况的每种情况下,如果用户转到“设置”>“Facebook”>“关闭我们的应用程序”>“打开我们的应用程序”,它就可以解决。他们回到我们的应用程序,点击“使用 Facebook 登录”,一切正常。
所以这是我的问题:
- 有没有办法从他们的 FB ACAccount 中持续获取用户的 oauthToken?正如您将在我的代码中看到的那样,我现在首先检查该值是否为空,如果是,我向它们发出警报。
- 它说什么用户可以通过进入设置来解决这个问题,禁用然后启用我的应用程序?他们的帐户不同步还是我需要更新凭据?
- 如果我被告知已授予访问权限但我未能收到 oauthToken,是否有办法在我的方法中恢复?
- 有谁知道我可以设置系统以便可靠地重现它的方法吗?
这是我的代码:
- (void)login
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *fbAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *appId = [[Environment sharedInstance] fbAppId];
NSDictionary *fbOptions = @{
ACFacebookAppIdKey : appId,
ACFacebookPermissionsKey : [@"email,user_birthday,user_hometown,user_location,user_photos" componentsSeparatedByString:@","],
ACFacebookAudienceKey: ACFacebookAudienceEveryone
};
[accountStore requestAccessToAccountsWithType:fbAccountType options:fbOptions completion:^(BOOL granted, NSError *error) {
NSString *message;
NSString *title;
if (!granted) {
if (!error || error.code == ACErrorPermissionDenied) {
title = @"AFAR Needs Your Permission";
message = @"Your Facebook account is configured in Settings. Go to Settings and enable AFAR.";
} else if (error.code == ACErrorAccountNotFound) {
title = @"No Facebook Account";
message = @"There are no Facebook accounts configured. You can add or create a Facebook account in Settings.";
}
if (message) {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AfarFacebookLoginDidNotSucceed object:nil];
[UIAlertView simpleAlertWithTitle:title message:message];
});
}
return;
}
ACAccount *fbAccount = [[accountStore accountsWithAccountType:fbAccountType] lastObject];
ACAccountCredential *fbCredential = [fbAccount credential];
NSString *accessToken = [fbCredential oauthToken];
if ([accessToken isEmpty]) {
message = @"You need to allow AFAR access to your Facebook account. Please visit Settings > Facebook and look for the AFAR entry. Turn the AFAR setting off, then back on.";
title = @"Problem Connecting to Facebook";
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AfarFacebookLoginDidNotSucceed object:nil];
[UIAlertView simpleAlertWithTitle:title message:message];
});
return;
}
[SessionAPIService signInUsingFacebookToken:accessToken withBlock:^(NSError *error) {
if (!error) {
[[NSNotificationCenter defaultCenter] postNotificationName:AFARCurrentUserDidSignInNotificatioName object:nil];
}
}];
}];
}