Fetching basic information (id, first_name) from Facebook by using Social Framework - source code and screenshots attached

StackOverflow https://stackoverflow.com/questions/20829767

سؤال

For what would be a word game later I am trying to fetch very basic information about a player by using Social framework:

  • id
  • first_name
  • gender
  • location

(i.e. nothing sensitive like email and I don't use Facebook iOS SDK).

So in Xcode 5.0.2 I create a blank single view app for iPhone and add Social.framework to the Build phases tab.

Then I add the following code to the ViewController.m:

#import "ViewController.h"
#import <Social/Social.h>
#import <Accounts/Accounts.h>

#define FB_APP_ID @"432298283565593"
//#define FB_APP_ID @"262571703638"

@interface ViewController ()
@property (strong, nonatomic) ACAccountStore *accountStore;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"Facebook is available: %d", [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]);

    [self getMyDetails];
}

- (void) getMyDetails {
    if (!_accountStore) {
        _accountStore = [[ACAccountStore alloc] init];
    }

    ACAccountType *facebookAccountType = [_accountStore
                                        accountTypeWithAccountTypeIdentifier: ACAccountTypeIdentifierFacebook];
    NSDictionary *options = @{
                              ACFacebookAppIdKey: FB_APP_ID,
                              ACFacebookPermissionsKey: @[@"basic_info"]};

    [_accountStore requestAccessToAccountsWithType:facebookAccountType
                                           options:options
                                        completion:^(BOOL granted, NSError *error)
    {
        if (granted) {
            NSLog(@"Basic access granted");
        } else {
            NSLog(@"Basic access denied %@", error);
        }
    }];
}

@end

And create a new Facebook app for which I specify de.afarber.MyFacebook as the iOS Bundle ID:

enter image description here

Finally at Apple iTunes Connect I create a new App ID and then a new app (with a dummy icon and even 2 iPhone screenshots attached):

enter image description here

enter image description here

My Xcode Info tab and the rest of the source code are unchanged:

enter image description here

UPDATE 2:

I have updated the source code as suggested by helpful comments, thank you.

Also, I have another Facebook game, which works well (since 1-2 years) for an Adobe AIR desktop and mobile apps (but now I try to learn native iOS programming) and I have tried its id 262571703638 without success.

And I have added FacebookAppID to MyFacebook-Info.plist as suggested by Mohit10 (it seems to me that it is needed for Facebook SDK only, while I try to use Social Framework - but it can't hurt...)

Now I get the debugger output:

2013-12-31 11:08:07.584 MyFacebook[3009:70b] Facebook is available: 1
2013-12-31 11:08:07.964 MyFacebook[3009:3903] Basic access granted

I just need to figure out, how to fetch the id, first_name, gender, location now (and if basic_info is really needed for that)...

هل كانت مفيدة؟

المحلول 2

There are a few things wrong with your code.

  • ACAccountStore *accountStore is going out of scope, it should be an instance variable.
  • You don't need the ACFacebookAudienceKey, that's for publishing.
  • You don't need the ACFacebookPermissionsKey as the properties you want are available by default

With these fixes your code still doesn't work for me, although it does work for my App ID. I get the the following error:

"The Facebook server could not fulfill this access request: Invalid application 432298283565593" UserInfo=0x1d5ab670 {NSLocalizedDescription=The Facebook server could not fulfill this access request: Invalid application 432298283565593}

Looks like there's something wrong with your app's Facebook configuration.

The only difference I can see is that my app is sandboxed and I'm logged in using my developer account. Good luck.

نصائح أخرى

With the helpful comments (thank you) I've finally been able to fetch some information with the following code:

#import "ViewController.h"
#import <Social/Social.h>
#import <Accounts/Accounts.h>

#define FB_APP_ID @"432298283565593"
//#define FB_APP_ID @"262571703638"

@interface ViewController ()
@property (strong, nonatomic) ACAccount *facebookAccount;
@property (strong, nonatomic) ACAccountType *facebookAccountType;
@property (strong, nonatomic) ACAccountStore *accountStore;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    if (NO == [SLComposeViewController isAvailableForServiceType: SLServiceTypeFacebook]) {
        [self showAlert:@"There are no Facebook accounts configured. Please add or create a Facebook account in Settings."];
        return;
    }

    [self getMyDetails];
}

- (void) getMyDetails {
    if (! _accountStore) {
        _accountStore = [[ACAccountStore alloc] init];
    }

    if (! _facebookAccountType) {
        _facebookAccountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    }

    NSDictionary *options = @{ ACFacebookAppIdKey: FB_APP_ID };

    [_accountStore requestAccessToAccountsWithType: _facebookAccountType
                                           options: options
                                        completion: ^(BOOL granted, NSError *error) {
        if (granted) {
            NSArray *accounts = [_accountStore accountsWithAccountType:_facebookAccountType];
            _facebookAccount = [accounts lastObject];

            NSURL *url = [NSURL URLWithString:@"https://graph.facebook.com/me"];

            SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
                                                    requestMethod:SLRequestMethodGET
                                                              URL:url
                                                       parameters:nil];
            request.account = _facebookAccount;

            [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
                NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData
                                                                                   options:NSJSONReadingMutableContainers
                                                                                     error:nil];
                NSLog(@"id: %@", responseDictionary[@"id"]);
                NSLog(@"first_name: %@", responseDictionary[@"first_name"]);
                NSLog(@"last_name: %@", responseDictionary[@"last_name"]);
                NSLog(@"gender: %@", responseDictionary[@"gender"]);
                NSLog(@"city: %@", responseDictionary[@"location"][@"name"]);
            }];
        } else {
            [self showAlert:@"Facebook access for this app has been denied. Please edit Facebook permissions in Settings."];
        }
    }];
}

- (void) showAlert:(NSString*) msg {
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:@"WARNING"
                                  message:msg
                                  delegate:nil
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
        [alertView show];
    });
}

@end

This prints my data:

id: 597287941
first_name: Alexander
last_name: Farber
gender: male
city: Bochum, Germany

If you have any improvement suggestions, you're very welcome.

As you have not made any changes in your .plist file, you need to add your FacebookAppID in your .plist file. From that I think it will be helpful to you get the user details and you will be able to integrate it from your settings also.enter image description here

The answer is simple

in viewDidLoad() use:

accountStore= [[ACAccountStore alloc]init];
facebookAccountType= [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

NSDictionary *options= @{
ACFacebookAudienceKey: ACFacebookAudienceEveryone,
ACFacebookAppIdKey: @"<YOUR FACEBOOK APP ID>",
ACFacebookPermissionsKey: @[@"public_profile"]

                          };


[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {

    if (granted) {
        NSLog(@"Permission has been granted to the app");
        NSArray *accounts= [accountStore accountsWithAccountType:facebookAccountType];
        facebookAccount= [accounts firstObject];
        [self performSelectorOnMainThread:@selector(facebookProfile) withObject:nil waitUntilDone:NO];

    } else {
        NSLog(@"Permission denied to the app");
    }
}];

/////And the function -(void)facebookProfile{

NSURL *url = [NSURL URLWithString:@"https://graph.facebook.com/me"];

//////Notice the params you need are added as dictionary ///Refer below for complete list ////https://developers.facebook.com/docs/graph-api/reference/user

NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:@"picture,id,name",@"fields", nil];

SLRequest *profileInfoRequest= [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:url parameters:param];
profileInfoRequest.account= facebookAccount;


[profileInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
    NSLog(@"Facebook status code is : %ld", (long)[urlResponse statusCode]);

    if ([urlResponse statusCode]==200) {

        NSDictionary *dictionaryData= [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];



    } else {

    }
}];


}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top