Thursday, 30 January 2014

iOS 6 Facebook Integration Tutorial - How to login to your Facebook account? How to fetch Facebook home timeline using graph API?

This tutorial talks about the complete walk through to facebook account login and then fetching home timeline.


Beginning with iOS6+ you can now make use of the integrated facebook sdk for easy app development. Facebook has released their iOS integrated sdk to enable developers easy connectivity and action to the facebook account in their apps.

That means there's no more OAuth hassles and complex integration headaches. So let's just quickly get started with login to our facebook account through our app.

Login to your facebook account using Facebook-iOS6 integration:

The first step is to get our app id from facebook, if you don't already have it you can get it by signing up your app from the facebook developers site this APP ID enables your app to connect:

ACAccountStore *accountStore = [[ACAccountStore alloc] init];

NSString *appID = @"yourAppId";


Then the next step is to get permission from the user to allow our app all access to his facebook account and we do this as shown in the small method below:

-(void)requestAccessFromUser{
//This line declares that we are looking for a facebook account
ACAccountType *accountTypeFacebook= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

//This line asks user what are the things we need permission for
NSDictionary *fbDictionary = [NSDictionary dictionaryWithObjectsAndKeys:appID,ACFacebookAppIdKey,@[@"email",@"user_photos", @"user_videos", @"read_stream"],ACFacebookPermissionsKey, nil];

[self.accountStore requestAccessToAccountsWithType:accountTypeFacebook  options:fbDictionary  completion:^(BOOL granted, NSError *error) {
       if (granted)
         {
             NSArray *fbAccounts = [self.accountStore accountsWithAccountType:accountTypeFacebook];
             ACAccount *acc=[fbAccounts objectAtIndex:0];
             NSString *username=[acc username];
             //If the permission is granted we have successfully fetched the user name
             NSLog(@"fb username:: %@", username);
         } else {
             NSLog(@"Access denied:: %@",error);
         }
     }];
}


Fetch user facebook timeline using Facebook-iOS6 integration:

Once we have been granted access by the user the next task is to fetch the news feed of the user which we do as shown below:

-(void)userTimeline{
    ACAccountType *accountTypeFacebook= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

    //Again we ask user his permission to access his timeline
    NSDictionary *fbDictionary = [NSDictionary dictionaryWithObjectsAndKeys:self.appID,ACFacebookAppIdKey,@[@"read_stream"],ACFacebookPermissionsKey, nil];
    [self.accountStore requestAccessToAccountsWithType:accountTypeFacebook options:fbDictionary completion: ^(BOOL granted, NSError *e) {
         if (granted) {
                //If granted to access his permission we will now fetch his timeline
                 [self getTimeline];
         } else {
             NSLog(@"error %@",e);            
         }
     }];
}



-(void)getTimeline{
    ACAccountType *accountTypeFB= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
   
   //Below is our graph api url to hit to fetch the timeline
    NSURL *requestURL = [NSURL URLWithString:@"https://graph.facebook.com/me/home"];

   //We can define the number of feeds we need from facebook below using the limit parameter
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"15", @"limit", nil];

  //This is a GET request!
    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook 
                                                      requestMethod:SLRequestMethodGET
                                                      URL:requestURL
                                                      parameters:params];
    request.account = [[self.accountStore accountsWithAccountType:accountTypeFB] objectAtIndex:0];
    self.facebookAccount=[[self.accountStore accountsWithAccountType:accountTypeFB] objectAtIndex:0];
    [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
        if(!error){
            //The timeline returned from facebook is a JSON data which we need to parse later on.
            NSMutableDictionary *timelineData =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
            NSLog(@"Here's our timeline: %@" , timelineData);
            //with every data there's paging url which we can use to get to next or previous feeds
        }else{
            NSLog(@"error: %@",error);
        }
    }];
}



How to post status on facebook with location and image?

Let's try to post a status on our facebook wall! Before we try to post a status that includes location and image we need to first get the latitude and longitude using the native apple location libraries. Once we are with the latitude, longitude and image we make the call something like this

-(void)postUserStatus:(NSString*)statusMessage withImage:(UIImage*)postImage andLatitude:(NSString*)latitude andLongitude:(NSString*)longitude{
    __block NSString *placeID;
    ACAccountStore *acStore = [[ACAccountStore alloc] init];
    ACAccountType *FBaccountType= [acStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    NSDictionary *permissionDictionary = @{ACFacebookAppIdKey: appID,
             ACFacebookPermissionsKey: @[@"publish_actions", @"publish_stream"],
             ACFacebookAudienceKey: ACFacebookAudienceFriends
   };
   [acStore requestAccessToAccountsWithType:FBaccountType options:permissionDictionary  completion:
     ^(BOOL granted, NSError *error) {
         if (granted) {
             //Now we have the permission to post a status message
             NSLog(@"permission granted");
             NSArray *accounts = [acStore accountsWithAccountType:FBaccountType];
             self.facebookAccount = [accounts objectAtIndex:0];

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

                 //This is crucial, normally when posting location I look for a good range (distance) with at least 10 check ins at that place so we don't end up getting irrelevant place id like 'my garage' etc 
                 NSMutableDictionary * params = [NSMutableDictionary
                       dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"SELECT page_id, name, description, display_subtext FROM place WHERE distance(latitude, longitude, '%@', '%@') < 1000 AND                                                                           checkin_count > 10", latitude, longitude], @"q", nil];

                 SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
                       requestMethod:SLRequestMethodGET
                       URL:requestURL
                       parameters:params];
                 request.account = self.facebookAccount;
                 [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
                       if(!error){
                         NSDictionary *locationDictionary = [[NSDictionary alloc] init];
                         *locationDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
                         placeID = *locationDictionary objectForKey:@"data"] objectAtIndex:0] valueForKey:@"page_id"];
                         NSData *imageData = UIImageJPEGRepresentation(postImage, 90);
                         [self shareStatus:imageData withCaption:statusMessage!=nil?statusMessage:@"" andLocationPageId:placeID];
                    }else{
                         NSLog(@"error :: %@",error);
                     }
                 ];
             }
         }else{
             NSLog(@"error posting::%@", error);
       }  
     }];
}

And here's our share status method that makes the call to post our status:

- (void)shareStatus:(NSData*)imageData withCaption:(NSString*)imageCaption andLocationPageId:(NSString*)locationPageId{
    NSURL *picURL = [NSURL URLWithString:@"https://graph.facebook.com/me/photos"];   
    NSDictionary *params;
    //The status now becomes the caption of our image and location is added with it
    params = @{@"name": imageCaption, @"place": [NSString stringWithFormat:@"%@", locationPageId]};
    SLRequest *merequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
                                              requestMethod:SLRequestMethodPOST
                                                        URL:picURL
                                                 parameters:params];
    [merequest addMultipartData:imageData
                       withName:@"source"
                           type:@"photo/jpeg"
                       filename:@"myImage"];
    merequest.account = self.facebookAccount;
    [merequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        NSString *response= [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
        if(!error){
            NSLog(@"post success::%@", response);
        }else
            NSLog(@"error %@", error.localizedDescription);
    }];
}


Now, That's it use the dictionary and parse the data show it up on your view and design it the way like! In the next post we will talk about likes, comments and their count for a post, also how to post a comment or like a post. Follow the blog for more.


Read more »

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Best Web Hosting