I'm trying to present the facebook share dialog from my iOS app.
This code opens the facebook app and shows the dialog:
FBShareDialogParams* params = [[FBShareDialogParams alloc] init];
params.link = urlToShare;
params.name = #"Test";
params.description = #"Description";
params.picture = [NSURL URLWithString:FB_IMG_URL];
BOOL canPresentShareDialog = [FBDialogs canPresentShareDialogWithParams:params];
if (canPresentShareDialog) {
[FBDialogs presentShareDialogWithParams:params clientState:nil handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if (error) {
if ([FBErrorUtility shouldNotifyUserForError:error]) {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Facebook-Error!" message:[FBErrorUtility userMessageForError:error] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
} else {
NSLog(#"SUCCESS");
}
}];
}
In the completion handler I want to know if the user canceled the action. The results dictionary should tell me that. However I only get didComplete=YES in the dictionary but not a completionGesture. The NSError object is always nil.
The results dictionary is explained here: https://developers.facebook.com/ios/share-dialog/
So the problem is I can't tell if the post was successful or not.
Is something wrong with my code?
As stated in the doc, the "completionGesture" field is "only available if the user logged into your app".
So if the user has never used Facebook login with your app before, you will not get that field, and will only see the "didComplete" field.
If I am not wrong then you want to know if user is unable to post the data on facebook because of some error or because he pressed cancel button. If this is the case then use the code given below
[FBDialogs presentShareDialogWithParams:shareParams
clientState:nil
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error publishing story.");
} else if (results[#"completionGesture"] && [results[#"completionGesture"] isEqualToString:#"cancel"]) {
NSLog(#"User canceled story publishing.");
} else {
NSLog(#"Story published.");
}
}];
its been taken from Facebook Developer Reference. Let me know if it helps. Thanks
Related
My facebook login with parse is working perfectly with no issues but the access token that is generated is not showing permission for friendlist although I gave that permission at the time of login. I came to know when I used facebook Graph API 'Friendlists'(fbID/friendlists) and the response array is empty. So, also run Graph API explorer with the same access token generated. It does not show me any error and data array is same empty and a debug message with
"The field 'friendlists' is only accessible on the User object after the user grants the 'read_custom_friendlists' permission"
This is the method I am using
WLLoginViewController *login = [[WLLoginViewController alloc]init];
login.fields = PFLogInFieldsFacebook;
NSArray *permission = [[NSArray alloc]initWithObjects:#"email",#"read_custom_friendlists",#"publish_actions",#"user_location",#"user_hometown",#"user_website",#"user_about_me",#"user_photos",#"user_friends",#"read_custom_friendlists", nil];
login.facebookPermissions = permission;
WLLoginViewController has inherited PFUserLoginManager and I am calling it from some other class.
- (void)logInViewController:(PFLogInViewController *)logInController didLogInUser:(PFUser *)user {
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"permissions%#",logInController.facebookPermissions);
if(result) {
if ([result valueForKey:#"hometown"]) {
NSString *nn = [[result valueForKey:#"hometown"] valueForKey:#"name"];
[user setValue:[[result valueForKey:#"hometown"] valueForKey:#"name"] forKey:#"hometown"];
}
if ([result valueForKey:#"location"]) {
[user setValue:[[result valueForKey:#"location"] valueForKey:#"name"] forKey:#"location"];
}
[user setObject:[result valueForKey:#"id"] forKey:kWLUser_FacebookId];
[user setObject:[result valueForKey:#"name"] forKey:kWLUser_Name];
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if([PFInstallation currentInstallation]) {
// save in background current installation.
[[PFInstallation currentInstallation] setObject:user forKey:#"user"];
[[PFInstallation currentInstallation]saveInBackground];
}
}];
[[ParseManager sharedInstance]saveDeviceToken:[[NSUserDefaults standardUserDefaults]objectForKey:#"DeviceToken"]];
[self dismissViewControllerAnimated:YES completion:nil];
}else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Could not login" message:#"Could not login to facebook, please try again" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
}];
}
This is the method which is which is running when the user return to the app from facebook.The nslog in the code is showing the permission perfectly which I gave.
And finally this is the method for handling facebook request
-(void)handleFacebookFriendsRequest {
NSString *queryParams = #"id,name,picture.width(350).height(250),location,hometown,likes.limit(100000),statuses.limit(1),languages";
[queryParams stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#",[FBSession activeSession].permissions);
NSLog(#"%#",[[FBSession activeSession].permissions description]);
NSLog(#"%#",[FBSession activeSession].accessTokenData.accessToken);
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"me/friends?fields=%#",queryParams] completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
//change For getting everything out
NSLog(#"%#",[result objectForKey:#"data"]);
[[ApplicationDataModel sharedInstance]setFacebookFriendsList:[result objectForKey:#"data"]];
[self facebookRequestDidLoad:result];
} else {
[self facebookRequestDidFailWithError:error];
}
}];
}
I am stuck badly need help. Thanks in advance
The read_custom_friendlists is not a default permission, as a result you have to go through the approval process for this feature (https://developers.facebook.com/docs/facebook-login/permissions/v2.2)
To submit items for approval go to:
developers.facebook.com -> My Apps -> Status & Review
Caveat: "People listed in the Roles section of your App Dashboard - including Admins, Developers and Testers - can grant any permission without review. If only people in these Roles will use your app, you don't need to submit it for Login Review."(https://developers.facebook.com/docs/apps/faq)
As an incident of a user taking some action in my app, I want to post an image to Facebook on their behalf. Let's assume the user has already granted me publish_actions permission in class LoginVC (one time permission is used for ad infinitum posting in the future). Then at some in the future, in ActionVC, I want to publish a photo to Facebook. How do I do that? Here is the method I need to implement:
- (void)publishPhoto:(UIImage *)image
{
//what goes in here?
}
So far I have been looking at the samples from Facebook. The closest I come is the following, but it seems to be using a Dialog. But I don't want the user to "know" that the photo is being posted. They already granted the permission and I want the posting to happen without their knowledge as it were. So some other action has triggered the call to publish...
For reference, the code from the Facebook sample looks like this
- (void)publishPhoto:(UIImage *)image
{
BOOL canPresent = [FBDialogs canPresentShareDialogWithPhotos];
NSLog(#"canPresent: %d", canPresent);
FBPhotoParams *params = [[FBPhotoParams alloc] init];
params.photos = #[image];
BOOL isSuccessful = NO;
if (canPresent) {
FBAppCall *appCall = [FBDialogs presentShareDialogWithPhotoParams:params
clientState:nil
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if (error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
isSuccessful = (appCall != nil);
}
if (!isSuccessful) {
[self performPublishAction:^{
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
connection.errorBehavior = FBRequestConnectionErrorBehaviorReconnectSession
| FBRequestConnectionErrorBehaviorAlertUser
| FBRequestConnectionErrorBehaviorRetry;
[connection addRequest:[FBRequest requestForUploadPhoto:image]
completionHandler:^(FBRequestConnection *innerConnection, id result, NSError *error) {
[self showAlert:#"Photo Post" result:result error:error];
if (FBSession.activeSession.isOpen) {
self.buttonPostPhoto.enabled = YES;
}
}];
[connection start];
self.buttonPostPhoto.enabled = NO;
}];
}
}
Sorry if this question seems too easy, but I am a newbie to Facebook SDK integration
Generally you definitely want the user to be aware that something is being posted on their behalf, but to answer your question, if they've already granted you publish permissions, then you can use the code in the second "if" statement that you posted above, where it calls FBRequest requestForUploadPhoto:
I'm trying to share to Facebook using code from their iOS game tutorial. The dialog pops up and the image and text I specified is present, but when I hit "Send" the loading bar appears, doesn't load, then I am redirected to my app. No errors are printed to the console and the app does not crash.
When I go on Facebook to check if the message has posted, I get the following:
"Oops, Something Went Wrong. There was a problem posting your status. We've logged the error and will look into it."
I've used this code in the previous app and it worked perfectly fine. I've updated the Facebook ID, Facebook Display Name, and URL Scheme in the plist.
Here is the code:
FacebookHandler class (derived from Facebook tutorial)
#import "FacebookHandler.h"
#implementation FacebookHandler
+ (void) Facebook_CreateNewSession
{
// initialize Facebook
FBSession* session = [[FBSession alloc] init];
[FBSession setActiveSession: session];
}
+ (void) Facebook_Login
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"email",
nil];
// Attempt to open the session. If the session is not open, show the user the Facebook login UX
[FBSession openActiveSessionWithReadPermissions:permissions allowLoginUI:true completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
{
// Did something go wrong during login? I.e. did the user cancel?
if (status == FBSessionStateClosedLoginFailed || status == FBSessionStateCreatedOpening) {
// If so, just send them round the loop again
[[FBSession activeSession] closeAndClearTokenInformation];
[FBSession setActiveSession:nil];
[self Facebook_CreateNewSession];
}
else
{
}
}];
}
+ (void) Facebook_PostToNewsFeedWithTitle:(NSString*)title withCaption:(NSString*)caption withDescription:(NSString*)description withLink:(NSString*)link withPictureURL:(NSString*)picURL
{
// check if user is logged in
if ([FBSession activeSession] == nil)
{
[FacebookHandler Facebook_CreateNewSession];
[FacebookHandler Facebook_Login];
}
// This function will invoke the Feed Dialog to post to a user's Timeline and News Feed
// It will attemnt to use the Facebook Native Share dialog
// If that's not supported we'll fall back to the web based dialog.
NSString *linkURL = link;
NSString *pictureURL = picURL;
// Prepare the native share dialog parameters
FBShareDialogParams *shareParams = [[FBShareDialogParams alloc] init];
shareParams.link = [NSURL URLWithString:linkURL];
shareParams.name = title;
shareParams.caption= caption;
shareParams.picture= [NSURL URLWithString:pictureURL];
shareParams.description = description;
if ([FBDialogs canPresentShareDialogWithParams:shareParams]){
[FBDialogs presentShareDialogWithParams:shareParams
clientState:nil
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error publishing story.");
} else if (results[#"completionGesture"] && [results[#"completionGesture"] isEqualToString:#"cancel"]) {
NSLog(#"User canceled story publishing.");
} else {
NSLog(#"Story published.");
}
}];
}else {
// Prepare the web dialog parameters
NSDictionary *params = #{
#"name" : shareParams.name,
#"caption" : shareParams.caption,
#"description" : shareParams.description,
#"picture" : pictureURL,
#"link" : linkURL
};
// Invoke the dialog
[FBWebDialogs presentFeedDialogModallyWithSession:nil
parameters:params
handler:
^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
NSLog(#"Error publishing story.");
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
NSLog(#"User canceled story publishing.");
} else {
NSLog(#"Story published.");
}
}}];
}
}
#end
My Call
[FacebookHandler Facebook_PostToNewsFeedWithTitle:title withCaption:caption withDescription:description withLink:link withPictureURL:picURL];
UPDATE
It seems to be a problem with the Facebook app. When trying it on a device with Facebook uninstalled, I am asked to log in and then it posts successfully. However, if Facebook is installed, it doesn't post.
I fix it by manually typing the "URL types" key at the plist file.
Don't copy paste the plist values from another plist file - it's Apple's bug!!!
Facebook content looks different in wall and home page , after posting the content from iOS app using facebook sdk of iOS,
Used Code : We are using following code for posting the data in facebook wall.
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"Found this app ", #"message",
#"AppName", #"name",
#"App Title", #"caption",
#"Description data", #"description",
#"Link URL", #"link",
#"Image URL", #"picture",nil];
// create the connection object.
FBRequestConnection *newConnection = [[[FBRequestConnection alloc] initWithTimeout:kRequestTimeoutInterval] autorelease];
// create the request object, using the fbid as the graph path as an alternative the request* static methods of the
// FBRequest class could be used to fetch common requests, such as /me and /me/friends
FBRequest *request=[[[FBRequest alloc] initWithSession:activeSession
graphPath:#"me/feed"
parameters:params
HTTPMethod:#"POST"] autorelease];
Detail: When we are going to post this data and link url ia available then content are looks different in home screen and profile screen .
Instead od App Name is display the Link URL title in home page but in profile page it display right content like App Title.
It happen only posting from iOS app , it looks good from Android app.
Please help Me tikamchandrakar#gmail.com or tikam.chandrakar#xymob.com
Let me know if any thing is not clear.
Thanks
Try This code. It works Perfect for me -
// Helper method to request publish permissions and post.
- (void)requestPermissionAndPost {
[FBSession.activeSession requestNewPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error && [FBSession.activeSession.permissions indexOfObject:#"publish_actions"] != NSNotFound) {
// Now have the permission
[self postOpenGraphAction];
} else if (error){
// Facebook SDK * error handling *
// if the operation is not user cancelled
if (error.fberrorCategory != FBErrorCategoryUserCancelled) {
// [self presentAlertForError:error];
}
}
}];
}
// Creates the Open Graph Action.
- (void)postOpenGraphAction {
NSString *pageId = #"";
if ([pageIdArray count] > 0) {
pageId = [[pageIdArray objectAtIndex:0] objectForKey:#"page_id"];
}else{
pageId = #"";
}
//http://mistoh.com/mistohws/CategoriesIcon/CategoryIcon_%1$s.png
[FBRequestConnection startWithGraphPath:#"me/feed"
parameters:#{
#"link":#"http://mistoh.com/mistohws/CategoriesIcon/CategoryIcon_1.png",
#"message":[NSString stringWithFormat:#"I just shared a Mistoh at %#",self.mistohNameStr],
#"place":[NSString stringWithFormat:#"%#",pageId],
#"name":[NSString stringWithFormat:#"%#",self.mistohNameStr],
#"description":[NSString stringWithFormat:#"%#",self.mistohDescStr],
#"address":[NSString stringWithFormat:#"%#",self.mistohAddressStr],
#"tags":[NSString stringWithFormat:#"%#",self.selectedFriendsStr]
}
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
//verify result
if (!error) {
[[[UIAlertView alloc] initWithTitle:#"Shared Mistoh Successfully!!"
message:#""
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil]
show];
}else{
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"Error while sharing mistoh with friends."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil]
show];
NSLog(#"Error : %#",[error description]);
}
}];
}
It looks good on facebook wall and timeline. Thank You..
I want to post text and link from iOS app to user timeline. I copy and paste FBWebDialogs example.
Problem 1:
The post appear in my timeline but the permission is "Only me", not friend or public.
Problem 2:
The result object (FBWebDialogResult) is nil. Log appear in my console.NSLog(#"User canceled story publishing.");
Problem 3:
The permission of preview box is "only me" even I set it to public
Attached setting of my Facebook page:
Here is my code:
[FBWebDialogs presentFeedDialogModallyWithSession:nil
parameters:params
handler:
^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// Error launching the dialog or publishing a story.
NSLog(#"Error publishing story.");
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User clicked the "x" icon
NSLog(#"User canceled story publishing.");
} else {
// Handle the publish feed callback
NSDictionary *urlParams = [self parseURLParams:[resultURL query]];
if (![urlParams valueForKey:#"post_id"]) {
NSLog(#"User canceled story publishing.");
} else {
NSString *msg = [NSString stringWithFormat:
#"Posted story, id: %#",
[urlParams valueForKey:#"post_id"]];
[[[UIAlertView alloc] initWithTitle:#"Result"
message:msg
delegate:nil
cancelButtonTitle:#"OK!"
otherButtonTitles:nil]
show];
}
}
}
}];
The setting page of my app is "only me" by default. I don't expect all my users change this setting here.
OMG. I stuggled for whole day but no progress. I found solution as soon as I ask question.
The problem is I copied inappropriate sample code. Ichanged to [FBSession openActiveSessionWithPublishPermissions] and problem solved.
Here is the login code I used. My post can be public now.
- (void)buttonRequestClickHandler:(id)sender {
// FBSample logic
// Check to see whether we have already opened a session.
if (FBSession.activeSession.isOpen) {
// login is integrated with the send button -- so if open, we send
// [self sendRequests];
NSLog(#"Login in facebook");
} else {
NSArray *permission = [NSArray arrayWithObjects:#"publish_actions", nil];
[FBSession openActiveSessionWithPublishPermissions:permission defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// if login fails for any reason, we alert
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
// if otherwise we check to see if the session is open, an alternative to
// to the FB_ISSESSIONOPENWITHSTATE helper-macro would be to check the isOpen
// property of the session object; the macros are useful, however, for more
// detailed state checking for FBSession objects
} else if (FB_ISSESSIONOPENWITHSTATE(status)) {
// send our requests if we successfully logged in
NSLog(#"Login in facebook"); }
}];
}