I am using the Facebook iOS SDK for iPhone. I initialize the Facebook instance
facebook = [[Facebook alloc] initWithAppId:kAppId];
And then
I thought may be I should make it a wiki and tell the people how I am doing it. because lot of people are facing similar problem.
The first thing that I did was.
In Facebook.m class I added the following statement in the following method
(void)authorizeWithFBAppAuth:(BOOL)tryFBAppAuth
safariAuth:(BOOL)trySafariAuth
trySafariAuth = NO;
This prevents a safari page to get open for the facebook login, but it pops up a screen in app itself. Then i created a helper class for Facebook, the header file code is here.
#import <UIKit/UIKit.h>
#import "FBConnect.h"
@interface FaceBookHelper : UIViewController
<FBRequestDelegate,
FBDialogDelegate,
FBSessionDelegate>{
Facebook *facebook;
NSArray *permissions;
}
@property(readonly) Facebook *facebook;
- (void)login;
-(void)getUserInfo:(id)sender;
- (void)getUserFriendList:(id)sender;
-(void)postToFriendsWall;
The .m file.
static NSString* kAppId = @"xxx";
#define ACCESS_TOKEN_KEY @"fb_access_token"
#define EXPIRATION_DATE_KEY @"fb_expiration_date"
@implementation FaceBookHelper
@synthesize facebook;
//////////////////////////////////////////////////////////////////////////////////////////////////
// UIViewController
/**
* initialization
*/
- (id)init {
if (self = [super init]) {
facebook = [[Facebook alloc] initWithAppId:kAppId];
facebook.sessionDelegate = self;
permissions = [[NSArray arrayWithObjects:
@"email", @"read_stream", @"user_birthday",
@"user_about_me", @"publish_stream", @"offline_access", nil] retain];
[self login];
}
return self;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject
- (void)dealloc {
[facebook release];
[permissions release];
[super dealloc];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// private
/**
* Login.
*/
- (void)login {
// only authorize if the access token isn't valid
// if it *is* valid, no need to authenticate. just move on
if (![facebook isSessionValid]) {
[facebook authorize:permissions delegate:self];
}
}
/**
* This is the place only where you will get the hold on the accessToken
*
**/
- (void)fbDidLogin {
NSLog(@"Did Log In");
NSLog(@"Access Token is %@", facebook.accessToken );
NSLog(@"Expiration Date is %@", facebook.expirationDate );
// Store the value in the NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY];
[defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY];
[defaults synchronize];
// This is the best place to login because here we know that user has already logged in
[self getUserInfo:self];
//[self getUserFriendList:self];
//[self postToFriendsWall];
}
- (void)fbDidNotLogin:(BOOL)cancelled {
NSLog(@"Failed to log in");
}
- (void)getUserInfo:(id)sender {
[facebook requestWithGraphPath:@"me" andDelegate:self];
}
- (void)getUserFriendList:(id)sender {
[facebook requestWithGraphPath:@"me/friends" andDelegate:self];
}
////////////////////////////////////////////////////////////////////////////////
// FBRequestDelegate
/**
* Called when the Facebook API request has returned a response. This callback
* gives you access to the raw response. It's called before
* (void)request:(FBRequest *)request didLoad:(id)result,
* which is passed the parsed response object.
*/
- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response {
NSLog(@"Inside didReceiveResponse: received response");
//NSLog(@"Status Code @", [response statusCode]);
NSLog(@"URL @", [response URL]);
}
/**
* Called when a request returns and its response has been parsed into
* an object. The resulting object may be a dictionary, an array, a string,
* or a number, depending on the format of the API response. If you need access
* to the raw response, use:
*
* (void)request:(FBRequest *)request
* didReceiveResponse:(NSURLResponse *)response
*/
- (void)request:(FBRequest *)request didLoad:(id)result {
NSLog(@"Inside didLoad");
if ([result isKindOfClass:[NSArray class]]) {
result = [result objectAtIndex:0];
}
// When we ask for user infor this will happen.
if ([result isKindOfClass:[NSDictionary class]]){
//NSDictionary *hash = result;
NSLog(@"Birthday: %@", [result objectForKey:@"birthday"]);
NSLog(@"Name: %@", [result objectForKey:@"name"]);
}
if ([result isKindOfClass:[NSData class]])
{
NSLog(@"Profile Picture");
//[profilePicture release];
//profilePicture = [[UIImage alloc] initWithData: result];
}
NSLog(@"request returns %@",result);
//if ([result objectForKey:@"owner"]) {}
};
/**
* Called when an error prevents the Facebook API request from completing
* successfully.
*/
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
//[self.label setText:[error localizedDescription]];
};
////////////////////////////////////////////////////////////////////////////////
// FBDialogDelegate
/**
* Called when a UIServer Dialog successfully return.
*/
- (void)dialogDidComplete:(FBDialog *)dialog {
//[self.label setText:@"publish successfully"];
}
@end
Thanks for this hint Yogesh!
In facebook.m you can also set the safariAuth param in the authorize method.
- (void)authorize:(NSArray *)permissions
delegate:(id<FBSessionDelegate>)delegate {
...
[self authorizeWithFBAppAuth:YES safariAuth:NO];
}