Episode #57

Facebook Integration

12 minutes
Published on March 14, 2013

This video is only available to subscribers. Get access to this video and 572 others.

In this episode we build on our Social App from episode 56 and add Facebook support. We cover setting up an Facebook application and the requisite permissions required to authenticate & fetch a user's friend list, all using the Social Framework in iOS 6.

Episode Links

Note - I was using a funky macro in this episode. There were 2 things I used, URLIFY to turn a string into a url, and NAVIFY to wrap a controller in a navigation controller. I'm not sure what I think about these just yet, but if you want to see them, they are in Macros.h

Requesting Access to a Facebook Account

Request access requires you to create an Facebook app first. Once you do, you'll need your App ID.

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    id options = @{
                   ACFacebookAppIdKey: @"223964394414685",
                   ACFacebookPermissionsKey: @[ @"email", @"read_friendlists"],
                   ACFacebookAudienceKey: ACFacebookAudienceFriends
                   };

Here we're requesting email and read_friendlists permissions. You need at least email, but you can add whatever you require here.

Next you need to actually request these accounts from the accountStore:

    [self.accountStore requestAccessToAccountsWithType:facebookAccountType
                                               options:options
                                            completion:^(BOOL granted, NSError *error) {
                                                if (granted) {
                                                    NSLog(@"Granted!");
                                                    ACAccount *fbAccount = [[self.accountStore accountsWithAccountType:facebookAccountType] lastObject];
                                                    [self fetchFacebookFriendsFor:fbAccount];
                                                } else {
                                                    NSLog(@"Not granted: %@", error);
                                                } 
                                            }];

Requesting the friends list

Requesting the friends list is easy, just make an authenticated request to https://graph.facebook.com/me/friends.

- (void)fetchFacebookFriendsFor:(ACAccount *)facebookAccount {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    SLRequest *friendsListRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
                                                       requestMethod:SLRequestMethodGET
                                                                 URL:URLIFY(@"https://graph.facebook.com/me/friends")
                                                          parameters:nil];
    friendsListRequest.account = facebookAccount;
    [friendsListRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        if (responseData) {
            NSLog(@"Got a response: %@", [[NSString alloc] initWithData:responseData
                                                               encoding:NSUTF8StringEncoding]);
            if (urlResponse.statusCode >= 200 && urlResponse.statusCode < 300) {
                NSError *jsonError = nil;
                NSDictionary *friendsListData = [NSJSONSerialization JSONObjectWithData:responseData
                                                                                options:NSJSONReadingAllowFragments
                                                                                  error:&jsonError];
                if (jsonError) {
                    NSLog(@"Error parsing friends list: %@", jsonError);
                } else {
                    self.friendsList = friendsListData[@"data"];
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self.tableView reloadData];
                    });
                }
            } else {
                NSLog(@"HTTP %d returned", urlResponse.statusCode);
            }
        } else {
            NSLog(@"ERROR Connecting");
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        });
    }];
}

Fetching images for the friends

Fetching images can be done by combining the friend's facebook id into the image url as shown here: https://graph.facebook.com/{id}/picture.

We do this in the cellForRowAtIndex: method to show the user's avatar & name on each row.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSDictionary *friend = self.friendsList[indexPath.row];
    NSLog(@"Friend: %@", friend);
    cell.textLabel.text = friend[@"name"];

    UIImage *defaultPhoto = [UIImage imageNamed:@"facebook_avatar.png"];
    NSString *urlString = [NSString stringWithFormat:@"https://graph.facebook.com/%@/picture", friend[@"id"]];
    NSURL *avatarUrl = URLIFY(urlString);
    [cell.imageView setImageWithURL:avatarUrl
                   placeholderImage:defaultPhoto];

    cell.imageView.contentMode = UIViewContentModeCenter;

    return cell;
}