I want to display display the Facebook login page in my app when the user is not signed-in yet. I'm using Facebook SDK for posting a status message on the users Facebook wall when the user allows the app.
Heres the code:
if (FBSession.activeSession.isOpen) {
// post to wall
#try {
[self postStatusMethod];
[self dismissViewControllerAnimated:YES completion:nil];
}
#catch (NSException *exception) {
NSLog(#"Error on posting to fb: %#", exception);
}
#finally {
}
} else {
// try to open session with existing valid token
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"read_stream",
#"publish_actions",
nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:session];
if([FBSession openActiveSessionWithAllowLoginUI:NO]) {
// post to wall
#try {
[self postStatusMethod];
[self dismissViewControllerAnimated:YES completion:nil];
}
#catch (NSException *exception) {
NSLog(#"Error on posting to fb: %#", exception);
}
#finally {
}
} else {
// you need to log the user
[self userLogin];
}
}
how do i create the userLogin function so that is will display this:
Then, go back to the same view controller. i am using Facebook sdk.
Finally, i build the code:
-(void) userLogin {
NSLog(#"Clicked!");
// If the session state is any of the two "open" states when the button is clicked
if (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
// Close the session and remove the access token from the cache
// The session state handler (in the app delegate) will be called automatically
[FBSession.activeSession closeAndClearTokenInformation];
// If the session state is not any of the two "open" states when the button is clicked
} else {
// Open a session showing the user the login UI
// You must ALWAYS ask for public_profile permissions when opening a session
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
}];
}
}
But it goes back to my main menu not on the same menu where i click it.
Related
I have a problem with the Facebook SDK in iOS. Everything works perfectly but I have a problem with the login flow. When the user hits the "log into Facebook" button he gets directed to Facebook to allow my app to get permissions. That's fine. But when iOS is changing from the browser to my app and trying to make a request I get this error message:
FBSDKLog: Error for request to endpoint 'search?q=concert&type=event&limit=10': An open FBSession must be specified for calls to this endpoint.
When I'm closing the app and start it again and go and execute my request it works without error. I get my reqeust. That´s my code I know its not very neat.
ViewdidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appDidEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
//Some other Code
if ([[FBSession activeSession]state])
{
NSLog(#"User is logged in");
[loginView setHidden:TRUE];
} else {
// try to open session with existing valid token
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"user_events",
nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:session];
if([FBSession openActiveSessionWithAllowLoginUI:NO]) {
} else {
NSLog(#"User is logged out");
//Create the FB Login-Button
loginView = [[FBLoginView alloc] initWithReadPermissions:#[#"user_events"]];
// Align the button in the center horizontally
loginView.frame = CGRectOffset(loginView.frame, (self.view.center.x - (loginView.frame.size.width / 2)), 200);
[self.view addSubview:loginView];
}
}
[self getEvents];
}
getEvents:
-(void)getEvents{
//Get General Events
[FBRequestConnection startWithGraphPath:#"search?q=concert&type=event&limit=10"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
//Some Code
else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
}
}];
}
appDidEnterForeground
- (void)appDidEnterForeground:(NSNotification *)notification {
NSLog(#"App did enter forground again.");
[self viewDidLoad];
}
ok, well I solved my own problem: I read through the docs again extremely carefully did everything again, added this to my delegate:
// Whenever a person opens the app, check for a cached session
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// If there's one, just open the session silently, without showing the user the login UI
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
// Handler for session state changes
// This method will be called EACH time the session state changes,
// also for intermediate states and NOT just when the session open
[self sessionStateChanged:session state:state error:error];
}];
}
}
// This method will handle ALL the session state changes in the app
-(void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error: (NSError *)error
{
// If the session was opened successfully
// customize your code...
}
and then I´m executing my method, which contains my request like this
// Logged-in user experience
- (void)loginViewShowingLoggedInUser:(FBLoginView *)loginView {
NSLog(#"You're logged in. (Method: loginviewshowingloggedinuser");
//If the User is logged in we can fetch the events
[self getEvents];
}
I am new to IOS and I created a Facebook custom login and logout buttons for my app using Facebook SDK. Login button works as I expected, but when I clicked my logout button, it gives the login page as I redirected to it. Then, when I try to login again, it doesn't show the Facebook login UI. But when I logged out my Facebook app and try to login to my app, the login UI works well. Here is my logout button.
- (IBAction)btnClicked:(id)sender {
[FBSession.activeSession closeAndClearTokenInformation];
NSLog(#"log out");
LoginUIViewController *loginController1= [[LoginUIViewController alloc] initWithNibName:#"LoginUIViewController" bundle:nil];
[self presentViewController:loginController1 animated:YES completion:nil];
}
Do I need to implement a logout button in my view controller or does FB SDK provides the logout facility it self?
# Vinod Jat,,
I made following changes in my appDelegate..
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[SplashViewController alloc] initWithNibName:#"SplashViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
// Whenever a person opens the app, check for a cached session
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// If there's one, just open the session silently, without showing the user the login UI
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
return YES;
}
//This method will handle ALL the session state changes in the app
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
// If the session was opened successfully
if (!error && state == FBSessionStateOpen){
NSLog(#"Session opened");
return;
}
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
// If the session is closed
NSLog(#"Session closed");
}
.........
}
**In my loginUIViewController I have added following method..**
- (IBAction)FbloginButton:(id)sender {
NSLog(#"inside login button");
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
NSLog(#"inside login button2");
// Retrieve the app delegate
TNLAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
// Call the app delegate's sessionStateChanged:state:error method to handle session state changes
[appDelegate sessionStateChanged:session state:state error:error];
NSLog(#"inside login button3");
}];
//redirect to now playing page
NowPlayingViewController *nowPlaying= [[NowPlayingViewController alloc] initWithNibName:#"NowPlayingViewController" bundle:nil];
[self presentViewController:nowPlaying animated:YES completion:nil];
}
I am using login with facebook in my app and getting username and profile pic from facebook. I have tested and it is working fine at my end, but apple has rejected it two times. I dont find any error at my end .
This is error by apple team:-
" We still found that your app exhibited one or more bugs, when reviewed on iPad Air running iOS 7.1 and an iPhone 5s running iOS 7.1, on both Wi-Fi and cellular networks, which is not in compliance with the App Store Review Guidelines.
Specifically, when we tap login to Facebook we get message say it wants to connect and when we tap ok it does not advance and connect with Facebook. "
Here is my Code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
self.login=[[ViewController alloc]init];
_nav = [[UINavigationController alloc] initWithRootViewController:self.login];
self.window.rootViewController = _nav;
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
// Whenever a person opens the app, check for a cached session
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
NSLog(#"Found a cached session");
// If there's one, just open the session silently, without showing the user the login UI
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info", #"email", #"user_likes"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
// Handler for session state changes
// This method will be called EACH time the session state changes,
// also for intermediate states and NOT just when the session open
[self sessionStateChanged:session state:state error:error];
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (error) {
NSLog(#"error:%#",error);
}
else
{
// retrive user's details at here as shown below
NSUserDefaults *storeData=[NSUserDefaults standardUserDefaults];
[storeData setObject:user.id forKey:#"user_id"];
[storeData setObject:user.name forKey:#"name"];
}
}];
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
}];
// If there's no cached session, we will show a login button
} else {
//UIButton *loginButton = [self.login loginButton];
//[loginButton setTitle:#"Log in with Facebook" forState:UIControlStateNormal];
}
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
// This method will handle ALL the session state changes in the app
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
// If the session was opened successfully
if (!error && state == FBSessionStateOpen){
NSLog(#"Session opened");
// Show the user the logged-in UI
[self userLoggedIn];
return;
}
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
// If the session is closed
NSLog(#"Session closed");
// Show the user the logged-out UI
[self userLoggedOut];
}
// Handle errors
if (error){
NSLog(#"Error");
NSString *alertText;
NSString *alertTitle;
// If the error requires people using an app to make an action outside of the app in order to recover
if ([FBErrorUtility shouldNotifyUserForError:error] == YES){
alertTitle = #"Something went wrong";
alertText = [FBErrorUtility userMessageForError:error];
[self showMessage:alertText withTitle:alertTitle];
} else {
// If the user cancelled login, do nothing
if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
NSLog(#"User cancelled login");
// Handle session closures that happen outside of the app
} else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession){
alertTitle = #"Session Error";
alertText = #"Your current session is no longer valid. Please log in again.";
[self showMessage:alertText withTitle:alertTitle];
// For simplicity, here we just show a generic message for all other errors
// You can learn how to handle other errors using our guide: https://developers.facebook.com/docs/ios/errors
} else {
//Get more error information from the error
NSDictionary *errorInformation = [[[error.userInfo objectForKey:#"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:#"body"] objectForKey:#"error"];
// Show the user an error message
alertTitle = #"Something went wrong";
alertText = [NSString stringWithFormat:#"Please retry. \n\n If the problem persists contact us and mention this error code: %#", [errorInformation objectForKey:#"message"]];
[self showMessage:alertText withTitle:alertTitle];
}
}
// Clear this token
[FBSession.activeSession closeAndClearTokenInformation];
// Show the user the logged-out UI
[self userLoggedOut];
}
}
// Show the user the logged-out UI
- (void)userLoggedOut
{
// Set the button title as "Log in with Facebook"
// UIButton *loginButton = [self.login loginButton];
//[loginButton setTitle:#"Log in with Facebook" forState:UIControlStateNormal];
// Confirm logout message
//[self showMessage:#"You're now logged out" withTitle:#""];
}
// Show the user the logged-in UI
- (void)userLoggedIn
{
// Set the button title as "Log out"
// UIButton *loginButton = self.login.loginButton;
//[loginButton setTitle:#"Log out" forState:UIControlStateNormal];
FrontViewController *v=[[FrontViewController alloc]init];
RearViewController *rearViewController = [[RearViewController alloc] init];
UINavigationController *frontNavigationController = [[UINavigationController alloc] initWithRootViewController:v];
UINavigationController *rearNavigationController = [[UINavigationController alloc] initWithRootViewController:rearViewController];
SWRevealViewController *revealController = [[SWRevealViewController alloc] initWithRearViewController:rearNavigationController frontViewController:frontNavigationController];
revealController.delegate = self;
[self.nav pushViewController:revealController animated:YES];
[self showMessage:#"You're now logged in" withTitle:#"Welcome!"];
}
// Show an alert message
- (void)showMessage:(NSString *)text withTitle:(NSString *)title
{
[[[UIAlertView alloc] initWithTitle:title
message:text
delegate:self
cancelButtonTitle:#"OK!"
otherButtonTitles:nil] show];
}
// During the Facebook login flow, your app passes control to the Facebook iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
// Override application:openURL:sourceApplication:annotation to call the FBsession object that handles the incoming URL
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Handle the user leaving the app while the Facebook login dialog is being shown
// For example: when the user presses the iOS "home" button while the login dialog is active
[FBAppCall handleDidBecomeActive];
}
In My View Controller
- (IBAction)buttonTouched:(id)sender
{
// If the session state is any of the two "open" states when the button is clicked
if (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
// Close the session and remove the access token from the cache
// The session state handler (in the app delegate) will be called automatically
[FBSession.activeSession closeAndClearTokenInformation];
// If the session state is not any of the two "open" states when the button is clicked
} else {
// Open a session showing the user the login UI
// You must ALWAYS ask for basic_info permissions when opening a session
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info", #"email", #"user_likes"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
// Retrieve the app delegate
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
// Call the app delegate's sessionStateChanged:state:error method to handle session state changes
[appDelegate sessionStateChanged:session state:state error:error];
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (error) {
NSLog(#"error:%#",error);
}
else
{
// retrive user's details at here as shown below
NSLog(#"FB user first name:%#",user.first_name);
NSUserDefaults *storeData=[NSUserDefaults standardUserDefaults];
[storeData setObject:user.id forKey:#"user_id"];
[storeData setObject:user.name forKey:#"name"];
}
}];
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
}];
}
}
Is your app on developer.facebook.com public and available for all users?
Status should look like this:
In other case if your app has status Developer Mode then other users can't authorise by Facebook.
I have exactly the same issue. Although it's a Flutter app, but the use-case is the same.
On my end, everything works as expected
Fb app has iOS and Bundle ID set correctly
FB app is public
But the Apple review team still rejects it. I asked for more Screenshots, which they provided, AND the screenshots clearly show the "continue" dialog of the FB-popup. So I don't understand why they rejected it.
I have an iPad app designed for use in a kiosk environment.
The user flow should be
Take Photo
Choose photo from iPad Album view
Share to Facebook and / or Twitter
Automatically log user out after image has been posted
I have the auto-logout of Twitter working properly, my issue is with the Facebook portion.
I have implemented the Graph API for internal testing, and would love to be able to post a complete story this way, but I don't think there is a way to log out from the Facebook app once the authorization and post is complete.
For a fallback, I can use the Feed Dialog and auto-logout from there, but as far as I can tell, there is no way to upload a local image for sharing to Facebook from there.
My Facebook Sharing code is as follows:
- (IBAction)facebookShare:(id)sender {
/// Package the image inside a dictionary
NSArray* image = #[#{#"url": self.mergeImages, #"user_generated": #"true"}];
// Create an object
id<FBGraphObject> object =
[FBGraphObject openGraphObjectForPostWithType:#"me/feed:photo"
title:#"a photo"
image:self.mergeImages
url:nil
description:nil];
// Create an action
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
// Set image on the action
[action setObject:image forKey:#"image"];
// Link the object to the action
[action setObject:object forKey:#"photo"];
// Hardcode the location based on Facebook Place ID
id<FBGraphPlace> place = (id<FBGraphPlace>)[FBGraphObject graphObject];
[place setId:#"279163865580772"]; // Singley + Mackie
[action setPlace:place];
// Check if the Facebook app is installed and we can present the share dialog
FBOpenGraphActionShareDialogParams *params = [[FBOpenGraphActionShareDialogParams alloc] init];
params.action = action;
params.actionType = #"me/feed:share";
// If the Facebook app is installed and we can present the share dialog
if([FBDialogs canPresentShareDialogWithOpenGraphActionParams:params]) {
// Show the share dialog
[FBDialogs presentShareDialogWithOpenGraphAction:action
actionType:#"photo_overlay:share"
previewPropertyName:#"photo"
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
// NSLog([NSString stringWithFormat:#"Error publishing story: %#", error.description]);
} else {
// Success
NSLog(#"result %#", results);
}
}];
// If the Facebook app is NOT installed and we can't present the share dialog
} else {
// Put together the Feed dialog parameters
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"name",
#"caption",
#"description",
#"link",
#"picture",
nil];
// Show the feed dialog
[FBWebDialogs presentFeedDialogModallyWithSession:nil
parameters:params
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
// NSLog([NSString stringWithFormat:#"Error publishing story: %#", error.description]);
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User cancelled.
NSLog(#"User cancelled.");
} else {
// Handle the publish feed callback
NSDictionary *urlParams = [self parseURLParams:[resultURL query]];
if (![urlParams valueForKey:#"post_id"]) {
// User cancelled.
NSLog(#"User cancelled.");
} else {
// User clicked the Share button
NSString *result = [NSString stringWithFormat: #"Posted story, id: %#", [urlParams valueForKey:#"post_id"]];
NSLog(#"result %#", result);
}
}
}
// Auto log the user out
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(#"defaults fbDidLogout ........%#",defaults);
if ([defaults objectForKey:#"FBAccessTokenKey"])
{
[defaults removeObjectForKey:#"FBAccessTokenKey"];
[defaults removeObjectForKey:#"FBExpirationDateKey"];
[defaults synchronize];
}
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
{
NSString* domainName = [cookie domain];
NSRange domainRange = [domainName rangeOfString:#"facebook"];
if(domainRange.length > 0)
{
[storage deleteCookie:cookie];
}
}
[FBSession.activeSession closeAndClearTokenInformation];
}];
}
}
// A function for parsing URL parameters.
- (NSDictionary*)parseURLParams:(NSString *)query {
NSArray *pairs = [query componentsSeparatedByString:#"&"];
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
for (NSString *pair in pairs) {
NSArray *kv = [pair componentsSeparatedByString:#"="];
NSString *val =
[kv[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
params[kv[0]] = val;
}
return params;
}
I have searched Stack Overflow far and wide for an answer to this, but have found no solutions.
I was finally able to figure this out! Posting the answer here to hopefully benefit others who are in the same situation.
First, add the following to your AppDelegate.m:
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication fallbackHandler:^(FBAppCall *call) {
// Facebook SDK * App Linking *
// For simplicity, this sample will ignore the link if the session is already
// open but a more advanced app could support features like user switching.
if (call.accessTokenData) {
if ([FBSession activeSession].isOpen) {
NSLog(#"INFO: Ignoring app link because current session is open.");
}
else {
[self handleAppLink:call.accessTokenData];
}
}
}];
}
// Helper method to wrap logic for handling app links.
- (void)handleAppLink:(FBAccessTokenData *)appLinkToken {
// Initialize a new blank session instance...
FBSession *appLinkSession = [[FBSession alloc] initWithAppID:nil
permissions:nil
defaultAudience:FBSessionDefaultAudienceNone
urlSchemeSuffix:nil
tokenCacheStrategy:[FBSessionTokenCachingStrategy nullCacheInstance] ];
[FBSession setActiveSession:appLinkSession];
// ... and open it from the App Link's Token.
[appLinkSession openFromAccessTokenData:appLinkToken
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
// Forward any errors to the FBLoginView delegate.
if (error) {
//[self.loginViewController loginView:nil handleError:error];
}
}];
}
Wherever you are calling the posting action in your app, add this line to your header file:
#property (strong, nonatomic) FBRequestConnection *requestConnection;
And the following to your implementation file:
#synthesize requestConnection;
- (IBAction)facebookShare:(id)sender {
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"publish_actions", #"publish_checkins", nil];
UIImage *img = self.facebookImage;
[FBSession openActiveSessionWithPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES
completionHandler:^(FBSession *session,FBSessionState s, NSError *error) {
[FBSession setActiveSession:session];
if (!error) {
// Now have the permission
[self processPostingImage:img WithMessage:#"Enter_your_message_here"];
} else {
// Facebook SDK * error handling *
// if the operation is not user cancelled
if (error.fberrorCategory != FBErrorCategoryUserCancelled) {
[self presentAlertForError:error];
}
}
}];
}
-(void)logout {
[FBSession.activeSession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession setActiveSession:nil];
}
- (void)processPostingImage:(UIImage *) img WithMessage:(NSString *)message {
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
FBRequestHandler handler =
^(FBRequestConnection *connection, id result, NSError *error) {
// output the results of the request
[self requestCompleted:connection forFbID:#"me" result:result error:error];
};
FBRequest *request=[[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:#"me/photos" parameters:[NSDictionary dictionaryWithObjectsAndKeys:UIImageJPEGRepresentation(img, 0.7),#"source",message,#"message",#"{'value':'EVERYONE'}",#"privacy", nil] HTTPMethod:#"POST"];
[newConnection addRequest:request completionHandler:handler];
[self.requestConnection cancel];
self.requestConnection = newConnection;
[newConnection start];
}
// FBSample logic
// Report any results. Invoked once for each request we make.
- (void)requestCompleted:(FBRequestConnection *)connection
forFbID:fbID
result:(id)result
error:(NSError *)error
{
// not the completion we were looking for...
if (self.requestConnection &&
connection != self.requestConnection)
{
return;
}
// clean this up, for posterity
self.requestConnection = nil;
if (error)
{
}
else
{
[self logout];
};
}
- (void) presentAlertForError:(NSError *)error {
// Facebook SDK * error handling *
// Error handling is an important part of providing a good user experience.
// When fberrorShouldNotifyUser is YES, a fberrorUserMessage can be
// presented as a user-ready message
if (error.fberrorShouldNotifyUser) {
// The SDK has a message for the user, surface it.
[[[UIAlertView alloc] initWithTitle:#"Something Went Wrong"
message:error.fberrorUserMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
} else {
}
}
Note:
To make this work with auto-logout, you also have to disable Safari on the device. This can be done by going to Settings > General > Restrictions > Allow Safari > Off. Once that is turned off, the Facebook IBAction will popup a UIWebView inside the app itself. When tapped, the current user can enter their Facebook credentials, then the app will post the image, and log the user out so the next user can use the app without having access to the previous user's Facebook details.
here is my code which is running properly but I want to use LoginWithFacebook default button which is provided by facebook.
Is there any image provided by facebook then please give me suggestion.
thankx in advance.....
#import "FacebbokViewController.h"
#import "UserAppAppDelegate.h"
#interface FacebbokViewController ()
#end
#implementation FacebbokViewController
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// button which I have used
UIButton *login=[[UIButton alloc]initWithFrame:CGRectMake(100,100, 200,80)];
[login setBackgroundColor:[UIColor blueColor]];
[login setTitle:#"login With facebook" forState:UIControlStateNormal];
[login setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[login addTarget:self action:#selector(loginWithFacebook) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:login];
}
// method which excute on my button click
-(IBAction)loginWithFacebook{
UserAppAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"email", nil];
if(!appDelegate.session.isOpen)
{
// create a fresh session object
appDelegate.session = [[FBSession alloc] init];
[FBSession setActiveSession: appDelegate.session];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
else{
NSLog(#"hi");
}
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
// If the session was opened successfully
if (!error && state == FBSessionStateOpen){
NSLog(#"Session opened");
[self userData]; // method created to fetch user’s data.
// Show the user the logged-in UI
// do all the things as you have the info you requested from facebook
return;
}
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
// If the session is closed
NSLog(#"Session closed");
// Show the user the logged-out UI
[FBSession.activeSession closeAndClearTokenInformation];
}
// Handle errors
if (error){
NSLog(#"Error");
NSString *alertText;
NSString *alertTitle;
// If the error requires people using an app to make an action outside of the app in order to recover
if ([FBErrorUtility shouldNotifyUserForError:error] == YES){
alertTitle = #"Something went wrong";
alertText = [FBErrorUtility userMessageForError:error];
[self showMessage:alertText withTitle:alertTitle];
} else {
// If the user cancelled login, do nothing
if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
NSLog(#"User cancelled login");
// Handle session closures that happen outside of the app
} else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession){
alertTitle = #"Session Error";
alertText = #"Your current session is no longer valid. Please log in again.";
[self showMessage:alertText withTitle:alertTitle];
// Here we will handle all other errors with a generic error message.
// We recommend you check our Handling Errors guide for more information
// https://developers.facebook.com/docs/ios/errors/
} else {
//Get more error information from the error
NSDictionary *errorInformation = [[[error.userInfo objectForKey:#"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:#"body"] objectForKey:#"error"];
// Show the user an error message
alertTitle = #"Something went wrong";
alertText = [NSString stringWithFormat:#"Please retry. \n\n If the problem persists contact us and mention this error code: %#", [errorInformation objectForKey:#"message"]];
[self showMessage:alertText withTitle:alertTitle];
}
}
// Clear this token
[FBSession.activeSession closeAndClearTokenInformation];
}
}
-(void)showMessage:(NSString*)alertMessage withTitle:(NSString*)alertTitle
{
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
-(void)userData
{
// Start the facebook request
[FBRequestConnection startWithGraphPath:#"me" parameters:[NSDictionary dictionaryWithObject:#"id,email" forKey:#"fields"] HTTPMethod:#"GET" completionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *result, NSError *error)
{
//if(!error){
// NSLog(#"result %#",result);
NSString *fbid =result[#"email"];
NSLog(#"result %#",fbid);
//}
}];
}
you can use FBLoginView to have the the functionality as your requirement , you can use like this
FBLoginView *loginView = [[FBLoginView alloc] init];
loginView.frame = YOURFRAME;
[self.view addSubview:loginView];
Take a look at FBLoginView in the Facebook SDK. Official link/tutorial. In the later part of the tutorial, implementing custom views and logging in with API calls is also covered. But note that you would have to design your button on your own in the latter case.