I'm trying to implement Game Request/Invite. Facebook is not returning any errors and I can share status in the user timeline using the same game/app configuration.
This is my code:
// -----------------------------------------------------------------------
//Facebook login
// -----------------------------------------------------------------------
- (void)fbLoginClicked:(id)sender
{
NSLog(#"-------------------------fbButtonClicked--------------------");
[[NSNotificationCenter defaultCenter] postNotificationName:#"LoginFaceBook" object:nil];
if (!FBSession.activeSession.isOpen) {
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
if (error) {
NSLog(#"error");
NSLog(#"message error %#", error.localizedDescription);
} else if (session.isOpen) {
NSLog(#"session is open");
[self pickFriendsButtonClick:sender];
//[self inviteFriends];
//[self publishResult];
//[self publishButtonAction];
NSLog(#"pick Friends button on click");
}
}];
}
}
// -----------------------------------------------------------------------
//Facebook pick friends
// -----------------------------------------------------------------------
- (void)pickFriendsButtonClick:(id)sender {
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: nil];
[FBWebDialogs presentRequestsDialogModallyWithSession:nil
message:[NSString stringWithFormat:#"I just smashed %d friends! Can you beat it?", score]
title:#"Smashing!"
parameters:params
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// Case A: Error launching the dialog or sending request.
NSLog(#"Error sending request.");
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// Case B: User clicked the "x" icon
NSLog(#"User canceled request.");
} else {
NSLog(#"Request Sent.");
}
}}
friendCache:nil];
}
I already checked my app settings in Facebook.
My Bundle ID is the same in my plist and I also have input my iPhone Store ID from AppStore.
And this is my code for share status on timeline, which is working great:
// -----------------------------------------------------------------------
//Share in Facebook
// -----------------------------------------------------------------------
- (void)publishResult {
// We want to upload a photo representing the gesture the player threw, and use it as the
// image for our game OG object. But we optimize this and only upload one instance per session.
// So if we already have the image URL, we use it, otherwise we'll initiate an upload and
// publish the result once it finishes.
NSLog(#"sharing operations starting");
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
NSMutableDictionary<FBOpenGraphObject> *game = [FBGraphObject openGraphObjectForPost];
game[#"type"] = #"fb_sample_rps:game";
game[#"title"] = #"an awesome game of Rock, Paper, Scissors";
game[#"data"][#"player_gesture"] = #"scissor";
game[#"data"][#"opponent_gesture"] = #"paper";
game[#"data"][#"result"] = #"win";
game[#"image"] = #"http://sandbox.yoyogames.com/extras/image/name/san2/853/404853/original/Game1.jpg";
NSLog(#"game object created");
FBRequest *objectRequest = [FBRequest requestForPostOpenGraphObject:game];
[connection addRequest:objectRequest
completionHandler:^(FBRequestConnection *innerConnection, id result, NSError *error) {
if (error) {
NSLog(#"tried to share, but Error: %#", error.description);
} else {
NSLog(#"message posted");
}
}
batchEntryName:#"objectCreate"];
NSString *message = #"teste 2";
[connection addRequest:[FBRequest requestForPostStatusUpdate:message]
completionHandler:^(FBRequestConnection *innerConnection, id result, NSError *error) {
NSLog(#"Error on post update feed");
}];
[connection start];
}
Already solved.
For some reason, my friend's Facebook version is an old one and don't receive any messages. For other friends with updated Facebook layout, it's working.
Related
i am using this code , to send Invite friend request for facebook freinds,this code give the message is User canceled request.
[FBRequestConnection startWithGraphPath:#"/me/friends"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
// NSLog(#"%#", result);
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSString stringWithFormat:#"%#", result], #"to", #"send", #"action_type", #"YOUR_OBJECT_ID", #"object_id", nil];
//for (NSDictionary *params in [result objectForKey:#"data"])
{
[FBWebDialogs
presentRequestsDialogModallyWithSession:nil
message:#"Learn how to make your iOS apps social."
title:nil
parameters:params
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// Error launching the dialog or sending request.
NSLog(#"Error sending request.");
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User clicked the "x" icon
NSLog(#"User canceled request.");
} else {
// Handle the send request callback
NSDictionary *urlParams = [appDelegate parseURLParams:[resultURL query]];
if (![urlParams valueForKey:#"request"]) {
// User clicked the Cancel button
NSLog(#"User canceled request.");
} else {
// User clicked the Send button
NSString *requestID = [urlParams valueForKey:#"request"];
NSLog(#"Request ID: %#", requestID);
}
}
}
}];
}
}];
Please check by adding only the following code and removing the block above this code.
[FBWebDialogs
presentRequestsDialogModallyWithSession: nil
message:#"Your invite message"
title:nil
parameters:nil
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(#"Error publishing story: %#", error.description);
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User canceled.
NSLog(#"User cancelled.");
} else {
// Handle the publish feed callback
}
}
}];
I am trying to follow the Parse tutorial for Logging in With Facebook. However, the sample code does not match up with the guide, so the code there is useless. I have followed the guide completely, but after I login, it directs me to Facebook app, I give permission, it goes back to the app I am building, but I get the following error
FBSDKLog: Error for request to endpoint 'me': An open FBSession must be specified for calls to this endpoint.
What is going on? In Login controller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// handle successful response
} else if ([[[[error userInfo] objectForKey:#"error"] objectForKey:#"type"]
isEqualToString: #"OAuthException"]) { // Since the request failed, we can check if it was due to an invalid session
NSLog(#"The facebook session was invalidated");
[self logoutButtonAction:nil];
} else {
NSLog(#"Some other error: %#", error);
}
}];
if ([PFUser currentUser] && // Check if user is cached
[PFFacebookUtils isLinkedWithUser:[PFUser currentUser]]) { // Check if user is linked to Facebook
// Present the next view controller without animation
[self _presentUserDetailsViewControllerAnimated:NO];
}
}
- (IBAction)loginButtonTouchHandler:(id)sender {
// Set permissions required from the facebook user account
NSArray *permissionsArray = #[ #"user_about_me", #"user_relationships", #"user_birthday", #"user_location"];
[PFFacebookUtils initializeFacebook];
// Login PFUser using Facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
[_activityIndicator stopAnimating]; // Hide loading indicator
if (!user) {
NSString *errorMessage = nil;
if (!error) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
errorMessage = #"Uh oh. The user cancelled the Facebook login.";
} else {
NSLog(#"Uh oh. An error occurred: %#", error);
errorMessage = [error localizedDescription];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Log In Error"
message:errorMessage
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Dismiss", nil];
[alert show];
} else {
if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
} else {
NSLog(#"User with facebook logged in!");
}
[self _presentUserDetailsViewControllerAnimated:YES];
}
}];
[_activityIndicator startAnimating]; // Show loading indicator until login is finished
}
- (void)_presentUserDetailsViewControllerAnimated:(BOOL)animated {
UserDetailsViewController *detailsViewController = [[UserDetailsViewController alloc] init];
[self.navigationController pushViewController:detailsViewController animated:YES];
}
In my UserDetailsViewController:
- (void)viewDidLoad {
// ...
[self _loadData];
}
- (void)_loadData {
// ...
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// result is a dictionary with the user's Facebook data
NSDictionary *userData = (NSDictionary *)result;
NSString *facebookID = userData[#"id"];
NSString *name = userData[#"name"];
NSString *location = userData[#"location"][#"name"];
NSString *gender = userData[#"gender"];
NSString *birthday = userData[#"birthday"];
NSString *relationship = userData[#"relationship_status"];
NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large&return_ssl_resources=1", facebookID]];
// URL should point to https://graph.facebook.com/{facebookId}/picture?type=large&return_ssl_resources=1
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:pictureURL];
// Run network request asynchronously
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError == nil && data != nil) {
// Set the image in the header imageView
self.headerImageView.image = [UIImage imageWithData:data];
}
}];
// Now add the data to the UI elements
// ...
}
}];
}
We figured it out, when trying to create an auto-login feature with this function:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// handle successful response
} else if ([[[[error userInfo] objectForKey:#"error"] objectForKey:#"type"]
isEqualToString: #"OAuthException"]) { // Since the request failed, we can check if it was due to an invalid session
NSLog(#"The facebook session was invalidated");
[self logoutButtonAction:nil];
} else {
NSLog(#"Some other error: %#", error);
}
}];
if ([PFUser currentUser] && // Check if user is cached
[PFFacebookUtils isLinkedWithUser:[PFUser currentUser]]) { // Check if user is linked to Facebook
// Present the next view controller without animation
[self _presentUserDetailsViewControllerAnimated:NO];
}
}
We actually end up skipping the [PFFacebookUtils initializeFacebook] call, since it only happens when you push the login button. The solution is to put this call in the appDelegate in the method application:didFinishLaunchingWithOptions:
I'm making a "FBRequestConnection" to get all the friends that play the game...
When I update the SDK of Facebook to the last one, this stop working. Because It was working before.
I have no respond, no success, no error. Any ideas?
NSString *query = #"SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user = 1";
// Set up the query parameter
NSDictionary *queryParam = [NSDictionary dictionaryWithObjectsAndKeys:query, #"q", nil];
// Make the API request that uses FQL
[FBRequestConnection startWithGraphPath:#"/fql"
parameters:queryParam
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
if (error) {
[self debug:[NSString stringWithFormat:#"Error: %#", [error localizedDescription]]];
} else {
[self debug:[NSString stringWithFormat:#"Result: %#", [result objectForKey:#"data"]]];
}
}];
-(void)fbLogin {
if (!_session.isOpen) {
// create a fresh session object
_session = [[FBSession alloc] init];
// if we don't have a cached token, a call to open here would cause UX for login to
// occur; we don't want that to happen unless the user clicks the login button, and so
// we check here to make sure we have a token before calling open
if (_session.state == FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[_session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// we recurse here, in order to update buttons and labels
[[NSNotificationCenter defaultCenter] postNotificationName:#"fbConnected" object:nil];
}];
}
[self populateUserDetails];
}
}
Thanks
Open the session with:
[FBSession.activeSession openWithCompletionHandler:^(FBSession * session, FBSessionState state, NSError * error){
if (!error){
}
}];
I'm using facebook sdk to post on friend's wall. I am able to post it but when i select multiple friends in FBWebDialog instead of posting two friends simultaneously for each friend a separate dialog box is shown. How to post on multiple friend's wall .
-(void)showFriendsList
{
friendPickerController = [[FBFriendPickerViewController alloc] init];
friendPickerController.title = #"Pick Friends";
friendPickerController.delegate = self;
[friendPickerController loadData];
}
-(IBAction)facebookShare:(UIButton *)sender
{
[friendPickerController presentModallyFromViewController:self animated:YES handler:
^(FBViewController *sender, BOOL donePressed) {
if (!donePressed)
{
return;
}
NSString* fid;
NSString* fbUserName;
for (id<FBGraphUser> user in friendPickerController.selection)
{
NSLog(#"\nuser=%#\n", user);
fid = user.id;
fbUserName = user.name;
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:remedyLabel, #"caption", appIcon, #"picture",symptomName, #"name",remedyDescription,#"description",fid,#"tags",fid,#"to",#"106377336067638",#"place", nil];
NSLog(#"\nparams=%#\n", params);
[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:#"%#/feed",fid] parameters:params HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection,id result,NSError *error)
{
[FBWebDialogs presentFeedDialogModallyWithSession:nil parameters:params handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error)
{
if (error)
{
NSLog(#"Error publishing story.");
}
else
{
if (result == FBWebDialogResultDialogNotCompleted) {
// User clicked the "x" icon
NSLog(#"User canceled story publishing.");
}
else
{
// Handle the publish feed callback
//Tell the user that it worked.
NSLog(#"Request Sent");
}
}
}];
}];
}
}];
}
No, that's not possible. You have to open separate dialog for each friend.
Using toblerpwn answer i manage to publish a picture to the application album as i wanted to.
But this works only when the application album has already been created (because i need to specify the album id).
In the other hand the requestForUploadPhoto convenience method creates the application album if it doesn't exists and publishes the picture.
So could someone help me figure out how to merge this two beheviours?
Thanks to #deepak-lakshmanan i manage to solve my problem.
The idea is to publish to the application album using /USER_ID/photos insted of /ALBUM_ID/photos; this way the album is automatically created if it doesn't exist.
So the steps to follow are:
get the publish permission
then retrieve the user id using /me
finally publish the picture to the application album with /USER_ID/photos
Here is my code in case someone struggles with this, am using Facebook SDK 3.1 for iOS:
- (void)sendRequestFacebookPublishPermission {
NSArray *permissions = [[NSArray alloc] initWithObjects:#"publish_stream", nil];
if(!FBSession.activeSession.isOpen ) {
[FBSession openActiveSessionWithPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
[self requestFacebookPublishPermissionCompleted:session status:status error:error];
}];
} else if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
[FBSession.activeSession reauthorizeWithPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
[self requestFacebookPublishPermissionCompleted:session status:FBSessionStateOpen error:error];
}];
} else {
[self sendRequesFacebooktUserInfo];
}
}
- (void)requestFacebookPublishPermissionCompleted:(FBSession *)session
status:(FBSessionState)status
error:(NSError *)error {
if (error) {
DLog(#"%#", error.localizedDescription);
} else {
[self sendRequesFacebooktUserInfo];
}
}
-(void)sendRequesFacebooktUserInfo {
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
// output the results of the request
FBRequestHandler handler = ^(FBRequestConnection *connection, id result, NSError *error) {
[self requestFacebookUserInfoCompleted:connection result:result error:error];
};
// create the request object, using the fbid as the graph path
FBRequest *request = [[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:#"me"];
// add the request to the connection object
[newConnection addRequest:request completionHandler:handler];
// if there's an outstanding connection, just cancel
[self.requestConnection cancel];
// keep track of our connection, and start it
self.requestConnection = newConnection;
[newConnection start];
}
- (void)requestFacebookUserInfoCompleted:(FBRequestConnection *)connection
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) {
DLog(#"%#", error.localizedDescription);
} else {
FBGraphObject *dictionary = (FBGraphObject *)result;
NSString* userId = (NSString *)[dictionary objectForKey:#"id"];
[self sendRequestFacebookPublishOnAlbum:userId];
}
}
- (void)sendRequestFacebookPublishOnAlbum:(NSString*)fbId {
UIImage *imageToPost = /* get the image you need*/ ;
/*
//--- Facebook SDK convenience method : requestForUploadPhoto won't let me post image description ---//
FBRequestConnection *newConnection = [FBRequestConnection startForUploadPhoto:screenshot completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[self requestPostCardOnFacebookCompleted:connection result:result error:error];
}];
// if there's an outstanding connection, just cancel
[self.requestConnection cancel];
// keep track of our connection, and start it
self.requestConnection = newConnection;
//-----------------------------------------------------------------------------------------------------//
*/
//--- http://stackoverflow.com/questions/12486852/facebook-ios-sdk-cannot-specify-an-album-using-fbrequests-requestforuploadphot ---//
NSString *messagePublie = laCarte.message;
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
screenshot, #"picture",
messagePublie , #"name",
nil] ;
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
FBRequestHandler handler = ^(FBRequestConnection *connection, id result, NSError *error) {
[self requestFacebookPublishOnAlbumCompleted:connection result:result error:error];
};
NSString *graphPath = [NSString stringWithFormat:#"%#/photos",fbId];
FBRequest *request = [[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:graphPath parameters:parameters HTTPMethod:#"POST"];
[newConnection addRequest:request completionHandler:handler];
// if there's an outstanding connection, just cancel
[self.requestConnection cancel];
// keep track of our connection, and start it
self.requestConnection = newConnection;
[newConnection start];
}
- (void)requestFacebookPublishOnAlbumCompleted:(FBRequestConnection *)connection result:(id)result error:(NSError *)error {
if (self.requestConnection && connection != self.requestConnection) {
return;
}
// clean this up, for posterity
self.requestConnection = nil;
if (error) {
DLog(#"%#", error.localizedDescription);
} else {
DLog(#"%#", "Done");
}
}