iosfacebookios6acaccount

When should I renew an ACAccount? Or, how to check if the credential is expired. (Facebook)


Recently I was assigned to survey how to use iOS framework ACAccount and Social to implement facebook post function. It is quite simple to gain access of the account configured in setting.

if(!_accountStore)
    _accountStore = [[ACAccountStore alloc] init];

ACAccountType *facebookTypeAccount = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

// Check if there is any faceboook account
NSArray *accounts = [_accountStore accountsWithAccountType:facebookTypeAccount];
if (![accounts count]) {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"alert" message:@"No facebook account configured in setting." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    return;
}

[_accountStore requestAccessToAccountsWithType:facebookTypeAccount
                                       options:@{ACFacebookAppIdKey: @"FACEBOOK-APP-ID", ACFacebookPermissionsKey: @[@"email"]}
                                    completion:^(BOOL granted, NSError *error) {
                                        if(granted){
                                            NSArray *accounts = [_accountStore accountsWithAccountType:facebookTypeAccount];
                                            _facebookAccount = [accounts lastObject];
                                            NSLog(@"Success");
                                        }else{
                                            // ouch
                                            NSLog(@"Failed, Error: %@", error);
                                            dispatch_async(dispatch_get_main_queue(), ^{
                                                NSString *message = [NSString stringWithFormat:@"App access denied, please grant access in Setting->Facebook. Error message::%@", error];
                                                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                                                [alert show];
                                            });
                                        }
                                    }];

Once the app gain access to facebook, it can post message by using SLComposeViewController:

- (IBAction)postButtonPressed:(id)sender {
if (!_facebookAccount) {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"alert" message:@"login first" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    return;
}

SLComposeViewController *fbController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
    SLComposeViewControllerCompletionHandler __block completionHandler=^(SLComposeViewControllerResult result){

        [fbController dismissViewControllerAnimated:YES completion:nil];

        switch(result){
            case SLComposeViewControllerResultCancelled:
            default:
            {
                NSLog(@"Cancelled.....");

            }
                break;
            case SLComposeViewControllerResultDone:
            {
                NSLog(@"Posted....");
            }
                break;
        }};

    [fbController setInitialText:@"Test message"];
    [fbController setCompletionHandler:completionHandler];
    [self presentViewController:fbController animated:YES completion:nil];
} else {
    NSLog(@"no facebook setup");
}

Here comes my question. I found that there is a method in ACAccountStore which is used to renew expired credential of an ACAccount:

- (void)renewCredentialsForAccount:(ACAccount *)account completion:(ACAccountStoreCredentialRenewalHandler)completionHandler;

But I don't even know how to check whether the credential is expired so that I can renew it. Anyone got an idea about this?

Oh, by the way, we just want to use the native Social framework to do simple work such as post some message or picture. So, if not needed, we are not going to use the facebook SDK.

If you know anything about how to check the credential is valid or not, please leave a comment or submit an answer, thank you:)

Updates 2013.11.20 11:10 AM

I learn something from my experiments to this issue..

  1. One is not able to get certain type of accounts from account store before he gains access to them, so I should not check account count before request for access.

  2. Renew notification called when the app using ACAccount is in background after facebook account changed. Currently, I only saw changes of access right triggers the notification.

  3. If the user changes password, the system will pop out an alert when the user attempt to post something, which ask the user to change password.

I think monitor notifications of account change is enough to handle the changes. I'll accept the first answer.


Solution

  • You should renew the user acc everytime it is out of sync. This may happen if the user has changed his password or when the acc session has expired.

    Yo can know you are in that scenario using the following notification:

    ACAccountStoreDidChangeNotification