27

I'm trying to perform a simple posting procedure:

- (IBAction)directPostClick:(id)sender {
    self.statusLabel.text = @"Waiting for authorization...";
    if (self.accountStore == nil) {
        self.accountStore = [[ACAccountStore alloc] init];
    }   
    ACAccountType * facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    NSArray * permissions = @[@"publish_stream", @"user_checkins", @"publish_checkins", @"user_likes", @"user_videos"];
    NSDictionary * dict = @{ACFacebookAppIdKey : @"My app id here", ACFacebookPermissionsKey : permissions, ACFacebookAudienceKey : ACFacebookAudienceOnlyMe};
    [self.accountStore requestAccessToAccountsWithType:facebookAccountType options:dict completion:^(BOOL granted, NSError *error) {
        __block NSString * statusText = nil;
        if (granted) {
            statusText = @"Logged in";
            NSArray * accounts = [self.accountStore accountsWithAccountType:facebookAccountType];
            self.facebookAccount = [accounts lastObject];
            NSLog(@"account is: %@", self.facebookAccount);
            self.statusLabel.text = statusText;
            [self postToFeed];
        }
        else {
            self.statusLabel.text = @"Login failed";
            NSLog(@"error is: %@", error);
        }
    }];
} 

EDITED: The problem is that when I click on alertView's OK button (don't allow doesn't work either) nothing happens! - This behavoir now changed with this iOS 6 Facebook posting procedure ends up with "remote_app_id does not match stored id" So instead of just "nothing happens" I've got an error "The Facebook server could not fulfill this access request: remote_app_id does not match stored id"

enter image description here

So , it seems that alert view's click handler doing nothing, my completionHandler is never called. I do have the similar problem already: iOS 6 Social integration - go to settings issue And I think that it is the same problem here. What do you guys think about it? P.S. I'm running on MAC mini, OS X 10.8.1 with latest xcode 4.5 (4G182) and using iPhone 6.0 simulator.

ADDED: By the Bjorn's request adding the postToFeed method although it is never called:

- (void)postToFeed {
    NSDictionary * parameters = @{@"message" : @"Hello world!"};
    NSURL * feedUrl = [NSURL URLWithString:@"https://graph.facebook.com/me/feed"];
    SLRequest * request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:feedUrl parameters:parameters];
    request.account = self.facebookAccount;
    [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.statusLabel.text = @"Posted!";
        });
    }];
}
Community
  • 1
  • 1
Stas
  • 9,925
  • 9
  • 42
  • 77
  • Could you please add the code of your `postToFeed` method? – Björn Kaiser Oct 01 '12 at 13:50
  • Yes sure, I'll add it to the question at the bottom – Stas Oct 01 '12 at 14:16
  • 1
    I'm not sure if this solved the problem for me when I had it, but make sure you've setup your App on Facebook correctly. Set the way it integrates with Facebook to "Native iOS App", fill out the Bundle ID (App Store ID can be 0 for now) and enable "Facebook Login". Additionally, set the "App Type" in the Advanced Tab to Native/Desktop. You may also set "App Secret in Client" to No. Let us know if that helped/was set correctly – Björn Kaiser Oct 01 '12 at 14:29
  • I cant find "Native iOS app" check-box..the rest was set correctly – Stas Oct 01 '12 at 14:40
  • It's in the "Basic Settings" of your Facebook App: "Select how your app integrates with Facebook" – Björn Kaiser Oct 01 '12 at 14:41
  • It seems that all options set correctly now..still does not work.. – Stas Oct 01 '12 at 15:15
  • After setting the bundle identifier the error changed to: The app must ask for a basic read permission at install time. So it seems that providing bundle identifier solved the problem with ids, thx Bjorn – Stas Oct 01 '12 at 15:46
  • As the error says, you may only ask for basic read permissions. This is `user_about_me` or `email`. Everything listed [here](https://developers.facebook.com/docs/authentication/permissions/) under "User and Friends Permissions" should be fine. Also notice that you may not ask for read/write permissions at the same time ;-) – Björn Kaiser Oct 01 '12 at 16:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/17431/discussion-between-stas-and-bjorn-kaiser) – Stas Oct 02 '12 at 06:05
  • sorry, forgot to award you with bounty ) – Stas Oct 06 '12 at 07:52

2 Answers2

97

I also experienced some difficulties when working with the Accounts Framework and the Facebook integration. Here is what I've learned and how I got it working.

1. Make sure you've setup your App on Facebook correctly
You need to set how your App integrates with Facebook to Native iOS App and enter the Bundle ID of your App into the designated field. (Edit: Note that bundle IDs are case sensitive) You can set the iTunes ID to 0 for now. Enable Facebook Login and set the App Type in the advanced settings tab to Native/Desktop.
Also set App Secret in Client to No.

If one or more of these options are not set correctly it's very likely you get the error The Facebook server could not fulfill this access request: remote_app_id does not match stored id.

(Edit: You also have to ensure the sandbox is disabled.)

2. Installing the Facebook App for the first time
When first installing an App via the native Facebook integration on iOS (and Mac OS X too), you must ask for a basic read permission only! Nothing else as email, user_birthday and user_location is allowed here. Using user_about_me, which is also a basic read permission according to the Facebook documentation, does not work. This is pretty confusing if you previously worked with the Facebook JavaScript SDK or the Facebook PHP SDK, because it asks for the basic permissions by default without you having to do something. Facebook also updated their documentation with a short step-by-step guide on how to use the new Facebook SDK on iOS 6.

3. Requesting additional permissions
It's important to know, that you may not ask for read and write permissions at the same time. That's also something experienced Facebook SDK developers may find confusing. Requesting the read_stream permission along with the publish_stream permission will make the request fail, resulting in the error An app may not aks for read and write permissions at the same time.

As Facebook does not really distinguish between read/write permissions in the Permission Reference, you must identify write permissions by yourself. They're usually prefixed with manage_*, publish_*, create_* or suffixed by *_management.

Facebook does also not recommend to ask for additional permissions immediately after getting basic permissions. The documentation says "You are now required to request read and publish permission separately (and in that order). Most likely, you will request the read permissions for personalization when the app starts and the user first logs in. Later, if appropriate, your app can request publish permissions when it intends to post data to Facebook. [...] Asking for the two types separately also greatly improves the chances that users will grant the publish permissions, since your app will only seek them at the time it needs them, most likely when the user has a stronger intent.".

4. Sample Code
The following sample code should work on iOS and Mac OS X:

ACAccountType * facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

// At first, we only ask for the basic read permission
NSArray * permissions = @[@"email"];

NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"My app id here", ACFacebookAppIdKey, permissions, ACFacebookPermissionsKey, ACFacebookAudienceOnlyMe, ACFacebookAudienceKey, nil];

[self.accountStore requestAccessToAccountsWithType:facebookAccountType options:dict completion:^(BOOL granted, NSError *error) {
    if (granted && error == nil) {
        /** 
        * The user granted us the basic read permission.
        * Now we can ask for more permissions
        **/
        NSArray *readPermissions = @[@"read_stream", @"read_friendlists"];
        [dict setObject:readPermissions forKey: ACFacebookPermissionsKey];

        [self.accountStore requestAccessToAccountsWithType:facebookAccountType options:dict completion:^(BOOL granted, NSError *error) {
            if(granted && error == nil) {
                /**
                * We now should have some read permission
                * Now we may ask for write permissions or
                    * do something else.
                **/
            } else {
                NSLog(@"error is: %@",[error description]);
            }
        }];
    } else {
        NSLog(@"error is: %@",[error description]);
    }
}];
Dickey Singh
  • 713
  • 1
  • 8
  • 16
Björn Kaiser
  • 9,882
  • 4
  • 37
  • 57
  • 2
    In step 1 be sure sure to look on the advanced tab in developer.facebook.com/apps for _App Type_ and _App Secret_. Also, Facebook says it'll take "several minutes" to hit all their servers, but it took about 30m I'd guess when I saw this with the Facebook 3.1.1 SDK. – a. brooks hollar Oct 04 '12 at 20:39
  • Hi, can u please tell me self.facebookAccount is which type . i mean what i have to declare? @Björn Kaiser – Babul Nov 27 '12 at 09:37
  • 1
    HI.. i set correctly as you said but still i am getting this error "The Facebook server could not fulfill this access request: The proxied app cannot request publish permissions without having being installed previously." @Björn Kaiser – Babul Nov 28 '12 at 10:06
  • Yes it is solved now i added user_about_me in the permissions now i changed to user_location @Björn Kaiser – Babul Nov 28 '12 at 10:12
  • But, It is not entering into this loop if(granted ) { NSArray *accountsArray = [accountStore accountsWithAccountType:accountType]; . Please Help me @Björn Kaiser – Babul Nov 28 '12 at 10:13
  • Thank u .. Good Explanation it helped me lot @Björn Kaiser – Babul Nov 28 '12 at 12:59
  • @BjörnKaiser Thanks . i want to give write permission and post message on my wall . i am used "https://graph.facebook.com/me/feed" url . but get status code 403 error . how can i post messag on using feed ? – Hitarth Dec 25 '12 at 10:54
  • @Coder, take a look on this q-a: http://stackoverflow.com/questions/13817590/facebook-ios-sdk-3-1-post-image-on-friends-wall-error/13818646#13818646 – Stas Dec 31 '12 at 09:39
  • I'm getting a "400" response, which I've ascertained is a "Bad Request" using SLRequest. How come this is so? I can select my account, and save it. Just there seems to be a missing access token? – topLayoutGuide Jan 07 '13 at 04:22
  • @BjörnKaiser Still getting the '400' response code and I'm at a loss. I didn't know I could tag you to notify you of my question.. – topLayoutGuide Jan 07 '13 at 05:35
  • @cocotouch Please open up a new question here on SO. Make sure to include all your relevant code and error messages. – Björn Kaiser Jan 07 '13 at 07:37
  • how a `NSDictionary *dict` can have `setObject` method? `setObject` is available for `NSMutableDictionary` only! – Vaibhav Saran Apr 11 '13 at 09:39
  • Oops, you're right. I fixed it, it's now a `NSMutableDictionary` as it should be. – Björn Kaiser Apr 11 '13 at 11:40
  • @Björn Kaiser Thank You. your answer is very helpful for solution of my facebook error. and for that i give you upvote. thanks..... – DharaParekh Apr 26 '13 at 13:33
  • When asking for basic permissions only, why are you asking for "email" permissions? Is that just a randomly selected basic permission? – zeeple Apr 30 '13 at 18:24
  • Sorry for getting back to you so late. Yes, I chose it randomly. I don't find the exact place in the documentation but as far as I remember you can chose between "email", "user_birthday", or "user_location". – Björn Kaiser May 21 '13 at 19:53
  • Giga-upvote. Thanks for clearing this annoyance up. –  Oct 14 '13 at 05:49
12

make sure sandbox mode is not activated if you are trying to access facebook account from application for non developer users.

Vaibhav Saran
  • 12,848
  • 3
  • 65
  • 75