Get Facebook access token from Social.framework(iOS6) - ios

I need to retrieve Facebook access token of my system account, which I set in Settings application.
I know that Social.framework(iOS6) knows all my FB account information & I can perform API calls to Graph API using SLRequest class, like in this post http://blogs.captechconsulting.com/blog/eric-stroh/ios-6-tutorial-integrating-facebook-your-applications
But, my question is - how can I retrieve my Facebook system account's access token?
I found solution for Twitter https://dev.twitter.com/docs/ios/using-reverse-auth , but could you help me with Facebook

If you already know how to get the account store set up, here's code around it showing how to get the access token:
#property (strong, nonatomic) ACAccountStore *accountStore;
#property (strong, nonatomic) ACAccount *fbAccount;
...
#synthesize accountStore = _accountStore;
#synthesize fbAccount = _fbAccount;
...
// Initialize the account store
self.accountStore = [[ACAccountStore alloc] init];
// Get the Facebook account type for the access request
ACAccountType *fbAccountType = [self.accountStore
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Request access to the Facebook account with the access info
[self.accountStore requestAccessToAccountsWithType:fbAccountType
options:fbInfo
completion:^(BOOL granted, NSError *error) {
if (granted) {
// If access granted, then get the Facebook account info
NSArray *accounts = [self.accountStore
accountsWithAccountType:fbAccountType];
self.fbAccount = [accounts lastObject];
// Get the access token, could be used in other scenarios
ACAccountCredential *fbCredential = [self.fbAccount credential];
NSString *accessToken = [fbCredential oauthToken];
NSLog(#"Facebook Access Token: %#", accessToken);
// Add code here to make an API request using the SLRequest class
} else {
NSLog(#"Access not granted");
}
}];

Related

Objective c How to retrieve Profile names of facebook and twitter from iPhone settings

I need to display the facebook and twitter profiles names in two labels
These profiles name should be getting from settings page setup
iif is there any facebook account setup in setting i have to get the user name and displaued it in my app
Same thing for twitter setup also how to achieve it.
Thanks,
Check in Settings
![enter image description here][2]
![enter image description here][3]
Using social framework, use you get details of accounts -
ACAccountStore *accountStore = [[ACAccountStore alloc] init] ;
ACAccountType *twitterAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:twitterAccountType withCompletionHandler:^(BOOL granted, NSError *error)
{
if(granted)
{
NSArray *twitterAccounts = [accountStore accountsWithAccountType:twitterAccountType];
NSLog(#"twitterAccounts %#", twitterAccounts);
}
}];
ACAccountType *facebookAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
//your app id is the key, i have used "Demo".
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:#"Demo", ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[accountStore requestAccessToAccountsWithType:facebookAccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *facebookAccounts = [accountStore accountsWithAccountType:facebookAccountType];
// fb accounts
NSLog(#"facebook accounts =%#", facebookAccounts);
} else {
//Error
NSLog(#"error getting permission %#",e);
}
}];
Similarly if there are more than 1 accounts configured, you can iterate through those and get the information.
EDIT - What are ACFacebookAppIdKey, ACFacebookPermissionsKey?
ACCOUNTS_EXTERN NSString * const ACFacebookAppIdKey NS_AVAILABLE(NA, 6_0); // Your Facebook App ID, as it appears on the Facebook website.
ACCOUNTS_EXTERN NSString * const ACFacebookPermissionsKey NS_AVAILABLE(NA, 6_0); // An array of of the permissions you're requesting.

Invalid token from Facebook ACAccount after removing app permission from Facebook Control Panel

I can correctly log into Facebook using the ACAccountStore account.
But if I delete the app from the Facebook Control Panel (https://www.facebook.com/settings?tab=applications), I get the following error when trying to get the user's friends :
{"error":
{"message":"Error validating access token: The user has not authorized
application XXXXXXXX.",
"type":"OAuthException","code":190,"error_subcode":458}}
If I delete the account from Settings, and re-login, the error goes away.
I'm using the following code to get the token, and use it in the requests. (snippet)
[self.store requestAccessToAccountsWithType:accountType
options:options
completion:^(BOOL granted, NSError *error) {
self.accounts = [self.store accountsWithAccountType:accountType];
NSMutableArray *availableAccounts = [NSMutableArray array];
self.account = self.accounts[0];
self.username = self.account.username;
self.userFullName = self.account.userFullName;
self.authToken = self.account.credential.oauthToken;
}]

How to save facebook account to ACAccountStore from facebookSDK

I want to save the facebook account to ACAccountStore in iOS,
I will get accessTocken from facebookSDK but how to obtain tocken and secret
How to save it to ACAccountStore
Thanks in Advance.
------ Edit--------
I have an application that uses facebook to login and after with login information need to share photos that he selected.
My use cases are,
If account already in settings app then I can use it for login and share.
User using safari or webview for login then how I can proceed for sharing.
a. facebook SDK says If the user need to use OS integrated share controller then, login method used to authenticate the user must be native iOS 6.0 authentication..
b. If I need to share option that provided by facebook SDK uses facebook App I don't want this option because I want to avoid App switching as much as possible.
How to solve this..
to do it you should have an accesstoken and secret,
if (self.accountStore == nil) {
self.accountStore = [[ACAccountStore alloc] init];
}
//make credentials to assign to ACAccount
ACAccountCredential *credential = [[ACAccountCredential alloc] initWithOAuthToken:accesstoken tokenSecret:secret];
ACAccountType *acctType =[self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
ACAccount *newAccount = [[ACAccount alloc] initWithAccountType:acctType];
newAccount.credential = credential;
NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys:
"xXXXXXX", (NSString *)ACFacebookAppIdKey,
[NSArray arrayWithObject:#"basic_info"], (NSString *)ACFacebookPermissionsKey,
ACFacebookAudienceEveryone, (NSString *)ACFacebookAudienceKey,
nil];
[_accountStore requestAccessToAccountsWithType:acctType options:options completion:^(BOOL granted, NSError *error) {
if (granted == YES) {
[self.accountStore saveAccount:newAccount withCompletionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"the account was saved!");
}
else {
if ([error code] == ACErrorPermissionDenied) {
NSLog(#"Got a ACErrorPermissionDenied, the account was not saved!");
}
NSLog(#"%#",error);
}
}];
}
else {
NSLog(#"%# ",error);
}
}];

ACAccountCredential returns null for oauthToken

I am getting access to user's facebook via:
[accStore requestAccessToAccountsWithType:fbAccountType
options:options
completion:^(BOOL granted, NSError *error) {
if (granted) {
// If access granted, then get the Facebook account info
NSArray *accounts = [accStore
accountsWithAccountType:fbAccountType];
ACAccount *acc = [accounts lastObject];
// Get the access token, could be used in other scenarios
ACAccountCredential *fbCredential = [acc credential];
NSString *accessToken = [fbCredential oauthToken];
NSLog(#"Facebook Access Token: %#", accessToken);
// Add code here to make an API request using the SLRequest class
} else {
NSLog(#"Access not granted");
}
}];
This prints out:
Facebook Access Token: (null)
I am granted access, but the token is null. What am I doing wrong?
Thanks
I've solved the problem by renewing the credentials. That is, after access to FB has been granted, but in the case where ACAccountCredential's oauthToken returns nil, we just call ACAccountStore's renewCredentialsForAccount. Credentials are renewed, and after that the token is valid!
Here's some info from Apple doc:
#property(nonatomic, retain) ACAccountCredential *credential
Discussion This property is required and must be set before the
account is saved. For privacy reasons, this property is inaccessible
after the account is saved.
As in your code, [acc credential] will return null
For reference, http://developer.apple.com/library/ios/#documentation/Accounts/Reference/ACAccountClassRef/Reference/Reference.html#//apple_ref/doc/uid/TP40011019
Found a similar post here: Get Facebook access token from Social.framework(iOS6)
Hope this can help.

When do we use saveAccount:(ACAccount *)account of ACAccountStore class?

Please clarify me when do we use this method ?
- (void)saveAccount:(ACAccount *)account withCompletionHandler:(ACAccountStoreSaveCompletionHandler)completionHandler
As I know we get access to the account through OAuth and we do not get user's credentials. So how do we create an account? I've found that ACAccount has the only one creation method:
- (id)initWithAccountType:(ACAccountType *)type
What actually happens when we create account this way? And can we save it now ?
Ok, finally I've found the information about it.
Consider this scenario:
Our app have already been authorized by the user and we've got both access token and secret. Now we want to support new iOS 6 features and create twitter (for example) account in Settings. To do this we need to migrate these tokens to the central account store.
Here's how:
- (void)storeAccountWithAccessToken:(NSString *)token secret:(NSString *)secret {
//We start creating an account by creating the credentials object
ACAccountCredential *credential = [[ACAccountCredential alloc] initWithOAuthToken:token tokenSecret:secret];
ACAccountType *twitterAcctType =[self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
ACAccount *newAccount = [[ACAccount alloc] initWithAccountType:twitterAcctType];
//Here we assign credentials and now can save account
newAccount.credential = credential;
[self.accountStore saveAccount:newAccount withCompletionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"the account was saved!");
}
else {
//Handle error here
}
}];
}
For more information about it read here how to migrate tokens

Resources