I have an app that has Facebook user_photos permissions enabled. The problem is if I go to Facebook and delete the app, iOS doesn’t notice this. ACAccountStore says I have permission, so requestAccess... returns “granted”, but as soon as I try an SLRequest, I get an error like Error validating access token: User XXXXX has not authorized application YYYYY and the app does not reappear in Facebook.
The workaround is to go to Settings->Facebook on the device, and toggle the permissions for my app off and back on. Next time I try the requestAccess, I get asked to confirm access again, and then the app reinstalls in Facebook and everything works.
ACAccountStore *accountStore = [[[ACAccountStore alloc] init] autorelease];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[accountStore requestAccessToAccountsWithType:accountType
options:@{ACFacebookAppIdKey: kFacebookAppID,
ACFacebookPermissionsKey: @[@"user_photos"]}
completion:^(BOOL granted, NSError *error)
{
if( error ) {
NSLog( @"account permission error %@", error );
}
else if( granted ) {
NSURL *requestURL = [NSURL URLWithString:@"https://graph.facebook.com/me/albums"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:[NSMutableDictionary dictionary]];
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
if( [accounts count] > 0 ) {
request.account = accounts[0];
[request performRequestWithHandler:^ (NSData *responseData, NSHTTPURLResponse *response, NSError *error)
{
if( error ) {
NSLog( @"error accessing Facebook account: %@", error );
}
else {
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
if( data[@"error"] != nil ) {
NSLog( @"error loading request: %@", data[@"error"] );
}
else {
NSLog( @"success! %@", data );
}
}
}];
}
else {
NSLog( @"error: no Facebook accounts" );
}
}
}];
In my case, I always get the final error (“error loading request: “) after deleting the app from Facebook, none of the other errors. After I toggle the app’s permission in the device’s Settings, I get success.
According to Apple, this works as intended (BS!). In practice, it turns out you have to get the
ACAccountStoresynchronized with Facebook by callingrenewCredentialsForAccountfirst. In this case, the result isACAccountCredentialRenewResultRejected. Then you can callACAccountStore requestAccessToAccountsOfTypeagain, and the user will finally be prompted to allow your app again.