问题
The documentation for the new Facebook SDK 3.0 tells us this:
"In some cases, the iOS device won't have an access token for a user who has already connected an app to their Facebook account. This can happen when a user used an app's website or used the app on another mobile device. To use the iOS 6 native Auth Dialog, apps need to 'import' the user's credentials into the device and need to show the iOS 6 native Auth Dialog."
(see http://developers.facebook.com/docs/howtos/ios-6/, tip 2)
I'd like to know how to import this data, I can't find a code example.
Thanks,
Tim
P.S. For information (and testing purposes) it's easy to reproduce the above situation in an app:
- In the settings app, delete the Facebook account
- In the app under development connect to Facebook via SSO, (it should fall back to this given that there's no Facebook account registered under iOS6
- Set up the Facebook account again in the settings app
- Once again, try signing in via the app under developement. This time it will still access Facebook via SSO since the token was created using it.
回答1:
As MrNickBarker suggested the solution is to log the user out of SSO. However, I only wanted to do this if I was absolutely sure that in doing so they user would be logged back in via the iOS 6 authentication system.
My problem was that I didn't know of a way of ensuring that the user was logged into Facebook via the Settings app, and I didn't want to log the user out of Facebook only to have them send back to the Facebook app for an SSO login each and every time.
None of the ACAccountStore methods will tell you if the user has entered their Facebook details into the Settings app, hwoever I finally discovered [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook] which does exactly this.
Here then is the solution:
ACAccountStore *accountStore = [[NSClassFromString(@"ACAccountStore") alloc] init];
ACAccountType *accountType;
if (accountStore &&
(accountType = [accountStore accountTypeWithAccountTypeIdentifier:@"com.apple.facebook"]) &&
[SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
{
// There's an account store and it knows about Facebook - we must be on iOS 6 or higher.
//
// [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook] also tells us that
// the user has signed into their Faecbook account via the Settings app.
//
// At this point there could be a valid session that's been previously created via SSO prior to the
// user signing into Facebook from Settings.app. In this case, calling openActiveSessionWithReadPermissions:
// will continue to log on using SSO rather than the preferred route of using the built in iOS support.
//
// [accountStore accountsWithAccountType:accountType] will return an account for this application once
// it's been used to log into Facebook. Clearly, if there is an account returned then the then we don't want to
// force a logout.
//
// On the other hand, if no accounts are returned then we can safely call closeAndClearTokenInformation
// in order to clear any SSO tokens, thereby ensuring that the next login will attempt to use the iOS
// authentication (which we can do since the user has signed into the Settings app).
if ([[accountStore accountsWithAccountType:accountType] count] == 0)
[FBSession.activeSession closeAndClearTokenInformation];
// Try to connect with read permissions only (as required for iOS auth)
_usingiOSIntegratedLogin = YES;
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:completionHandler];
}
else
{
// Either this is < iOS 6, or there's no Facebook account registered - request both
// read and write permissions in order to avoid two trips to the Facebook app or web view
_usingiOSIntegratedLogin = NO;
NSMutableArray *permissions = [NSMutableArray arrayWithArray:[self publishPermissions]];
[permissions insertObject:@"user_photos" atIndex:0];
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:completionHandler];
}
回答2:
In some cases, the iOS device won't have an access token for a user who has already connected an app to their Facebook account. This can happen when a user used an app's website or used the app on another mobile device. To use the iOS 6 native Auth Dialog, apps need to "import" the user's credentials into the device and need to show the iOS 6 native Auth Dialog. A good way to do this is to request basic profile information - see Step 1 above.
Notice the bolded text, just request access with basic premissions i.e. openActiveSessionWithPremissions:... and the session will hold the access token.
If it still uses SSO, first closeAndClearTokenInformation on the active session.
回答3:
While the roundabout accepted answer probably works, this functionality is built into the Facebook SDK. What you are looking for is FBSession openWithBehavior:completionHandler:
method and specify a behavior of FBSessionLoginBehaviorUseSystemAccountIfPresent
. It requires a little bit of extra work because you can't use the convenience class method FBSession openActiveSessionWithReadPermissions:allowLoginUI:completionHandler:
. But the extra work to initialize a session and then set the active session is trivial.
来源:https://stackoverflow.com/questions/12749027/importing-users-facebook-credentials-into-ios6