ACAccountStore not retrieving Facebook Account for Custom SLRequest - ios

Currently, I'm building an app that utilizes the new iOS 6 Social framework to gather a Facebook account stored in iOS, and create a custom SLRequest to post a status update and photo to the user's timeline. I have configured an app in the Facebook Dev Center, and have received my App ID, however, when I try to request the Facebook account through ACAccountStore, I always get the following localized error message:
2012-10-14 17:34:46.429 Status Update[12042:4c0b] The operation couldn’t be completed. (com.apple.accounts error 8.)
Here's the code that I'm currently using to process the request to get the account from the Account Store:
NSDictionary *options = #{
#"ACFacebookAppIdKey" : #"XXXXXXXXXXXXXXX",
#"ACFacebookPermissionsKey" : #[#"publish_stream"],
#"ACFacebookPermissionGroupKey" : #[#"write", #"email"]};
self.facebookStore = [[ACAccountStore alloc] init];
self.facebookAccountType = [self.facebookStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
self.facebookAccount = [[ACAccount alloc] initWithAccountType:self.facebookAccountType];
[self.facebookStore requestAccessToAccountsWithType:self.facebookAccountType options:options completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accounts = [self.facebookStore accountsWithAccountType:self.facebookAccountType];
self.facebookAccount = [accounts lastObject];
NSLog(#"Facebook Account Enabled: %#", _facebookAccount);
}
else
{
NSLog([NSString stringWithFormat:#"%#", error.localizedDescription]);
}
}];

Please take a look at: http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html
And note:
When requesting access to Facebook accounts, the only key required in your options dictionary is ACFacebookAppIdKey. ACFacebookPermissionGroupKey and ACFacebookAppVersionKey are now obsolete.
If you request a write permission under ACFacebookPermissionsKey, such as publish_stream, you must provide a value for ACFacebookAudienceKey, which can be one of ACFacebookAudienceEveryone, ACFacebookAudienceFriends, or ACFacebookAudienceOnlyMe.
NSDictionary *options = #{
ACFacebookAppIdKey: #"XXXXXXXX",
ACFacebookPermissionsKey: #[#"publish_stream"],
ACFacebookAudienceKey: ACFacebookAudienceFriends
};

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.

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);
}
}];

Social, Accounts framework to get user info from facebook (profile image,name,etc)

This is my facebook method:
- (void)getMeFacebook{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
__block ACAccount *facebookAccount = nil;
ACAccountType *facebookAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Specify App ID and permissions
NSDictionary *options = #{ACFacebookAppIdKey : #"1405219416361729",
ACFacebookPermissionsKey : #[#"email", #"publish_stream"],
ACFacebookAudienceKey:ACFacebookAudienceFriends};
[accountStore requestAccessToAccountsWithType:facebookAccountType
options:options completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
facebookAccount = [accounts lastObject];
NSLog(#"Granted!!!");
}
else {
NSLog(#"error.localizedDescription======= %#", error.localizedDescription);
}
}];
NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
facebookAccount = [accounts lastObject];
NSLog(#"Break 1");
When debugging the code, it never evaluates if(granted), seems like the method requestAccessToAccountsWithType is not behaving correctly.I have already check for the facebook settings in the app but still not working.
Any idea of this issue?
After some hours of debugging and research i reach the solution, everytime you have to debug a block (callback) of a method in objective-c, its needed to add extra breaktimes inside the block.
The issue was a problem of synchronism, as the method was call in the main.m and the UIAlert requesting permission to access facebook data in the iPhone never appears. I move the call of the method to the viewDidLoad and the entire app work ok!

requestAccessToAccountsWithType Returns NSError of "(NULL)"

I am using this code to connect to Facebook. It works the first time. Then I go into my Settings App and revoke the permissions. Then I go back into my app and run this code again. granted returns NO but the error does not contain any data, I am expecting error code 6, but I am getting "(null)"
if (!_accountStore) _accountStore = [[ACAccountStore alloc] init];
ACAccountType *fbActType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Permissions
NSArray *permissions = [NSArray arrayWithObject:#"email"];
NSMutableDictionary *options = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"##########", ACFacebookAppIdKey,
permissions, ACFacebookPermissionsKey,
nil];
// requestAccessToAccountsWithType
[_accountStore requestAccessToAccountsWithType:fbActType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
// do something if we have access
} else {
NSLog(#"%#",error); // this returns "(null)"
}
Any ideas why this is happening?
I had this problem and just stumbled across the answer in my case. The answer to this other question actually helped me find it.
I enabled my Facebook app as a native app, in developers.facebook.com (Settings->Advanced.)
I made my first request as a read just of #“email”.
NSDictionary *options = #{
ACFacebookAppIdKey: #“MY_FB_APP_ID",
ACFacebookPermissionsKey: #[#"email"],
};
That seems to "prime the pump” and subsequent requests for other permissions (reads and writes must be requested separately) have worked well. For example:
NSDictionary *options = #{
ACFacebookAppIdKey: #“MY_FB_APP_ID",
ACFacebookPermissionsKey: #[#"email",
#"user_friends"],
};

ACAccountStore Error 6 (ACErrorAccountNotFound) and 8

I'm attempting to get an account from ACAccountStore using the following code:
- (void) facebookLoginOnSuccess: (void (^)(void)) successBlock onError:(void(^)(NSError *error))errorBlock{
self.facebookPermissions = #[
#"offline_access",
#"publish_stream",
#"user_birthday",
#"user_location",
#"email"
];
NSDictionary *options = #{
#"ACFacebookAppIDKey": [[NSBundle mainBundle] objectForInfoDictionaryKey:#"FacebookAppID"],
#"ACFacebookAppVersionKey": #"1.0",
#"ACFacebookPermissionsKey": self.facebookPermissions,
#"ACFacebookPermissionGroupKey": #"write"
};
[self accountLoginFor:ACAccountTypeIdentifierFacebook withOptions:options OnSuccess:successBlock onError:errorBlock];
}
- (void) accountLoginFor: (NSString *) accountTypeID withOptions: (NSDictionary *) options OnSuccess: (void (^)(void)) successBlock onError:(void(^)(NSError *error))errorBlock{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:accountTypeID];
[accountStore requestAccessToAccountsWithType:accountType
options:options
completion:^(BOOL granted, NSError *error){
if (granted){
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
NSLog(#"%#",accountsArray);
}
else {
NSLog(#"Error accessing account: %#", [error localizedDescription]);
}
}];
}
But I'm getting this error:
Error Domain=com.apple.accounts Code=6 "The operation couldn't be completed. (com.apple.accounts error 6.)"
And I can't find anything related, just this question. Any ideas what could be wrong?
Update
I found this on the Apple Developer Docs.
Accounts Framework
When requesting access to Facebook accounts, the only key required in your options dictionary is ACFacebookAppIdKey. ACFacebookPermissionGroupKey and ACFacebookAppVersionKey are now obsolete.
If you request a write permission under ACFacebookPermissionsKey, such as publish_stream, you must provide a value for ACFacebookAudienceKey, which can be one of ACFacebookAudienceEveryone, ACFacebookAudienceFriends, or ACFacebookAudienceOnlyMe.
So I changed my options to:
NSDictionary *options = #{
#"ACFacebookAppIDKey": [[NSBundle mainBundle] objectForInfoDictionaryKey:#"FacebookAppID"],
#"ACFacebookPermissionsKey": self.facebookPermissions,
#"ACFacebookAudienceKey": ACFacebookAudienceFriends
};
But I'm getting the same error.
Ok so if you haven't setup an account from your Settings in iOS 6 it throws error code 6. If the user simply denies permission than it throws error code 7. In case 6 i suggest you ask the user to first setup her account in Settings.
NSDictionary *options = #{
ACFacebookAppIdKey: #"1234567890",
ACFacebookPermissionsKey: #[#"publish_stream"],
ACFacebookAudienceKey: ACFacebookAudienceFriends
};
[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
if([accounts count]>0)
self.facebookAccount = [accounts lastObject];
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
// Fail gracefully...
NSLog(#"%#",error.description);
if([error code]== ACErrorAccountNotFound)
[self throwAlertWithTitle:#"Error" message:#"Account not found. Please setup your account in settings app."];
else
[self throwAlertWithTitle:#"Error" message:#"Account access denied."];
});
}
}];
jAmi has the right idea, but I don't like the idea of the magic numbers in the code. There is an enum that has the numbers built into it (ACErrorCode).
My own solution was to use Facebook SDK instead of trying with the lib directly and now it's working.

Resources