I'm creating an game where I have a share button. In this share button I would like to share text and a link. It is important that the user can't edit the text since they would be able to change the score. What is the best solution for this? I've searched, but in most guides, you're able to change the text as a user.
What's the solution?
The short answer is that you're not supposed to post something on a user's behalf without giving them the option of editing the comment/status. You can do it with an API call (rather than a share sheet), but this should only be used to post content that the user entered elsewhere in the app.
// NOTE: pre-filling fields associated with Facebook posts,
// unless the user manually generated the content earlier in the workflow of your app,
// can be against the Platform policies: https://developers.facebook.com/policy
[FBRequestConnection startForPostStatusUpdate:#"User-generated status update."
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Status update posted successfully to Facebook
NSLog(#"result: %#", result);
} else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
NSLog(#"%#", error.description);
}
}];
This is from Facebook's "Sharing in iOS" documentation
Another option (though possibly also against the rules) is to create an image from the text and let the user share the image. Before doing this, however, put yourself in the user's shoes - do you really need to post something like that?
Related
After being able to create a small iOS app that logs in to Facebook. I would like this app to get the user’s list of friends.
Though I browsed the internet for a while and tried various approach I did not succeed to get what I wanted.
In the viewDidLoad method I use this code to start with:
loginView = [[FBLoginView alloc] initWithReadPermissions:#[#"user_friends"]];
And then I implement the loginViewFetchedUserInfo: user: method this way:
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user
{
[FBRequestConnection startWithGraphPath:#"/me/friends"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSLog(#“Result: %#",result);
}];
}
When I execute the app I get this result:
Result: {
data = (
);
summary = {
"total_count" = 267;
}; }
But what I really want is a list of the friends with their names …etc…
All the things I tried for that didn’t work. Though I suppose the solution must be simple.
I also used code like this in the method above ….. but with no luck:
NSArray* friends = [result objectForKey:#"data"];
One more point, here https://developers.facebook.com/docs/graph-api/reference/v2.1/user/friends one can read:
This will only return any friends who have used (via Facebook Login)
the app making the request.
But the result I get (267) does not match this statement. It (267) is the number of friends the user has on Facebook, which is in fact what I am interested in.
I hope someone has something to say to put me on the right track and make things clearer.
Since Facebook's 2.x SDK upgrade they have tightened up access to information in the "Open Graph API."
Under Permissions That Do Not Require Review
App friends. This optional permission grants your app the ability to read a list of friends who also use your app.
You get automatic access to any friends that already use your app (per its Facebook ID.)
You will have to request Extended Permissions if you want to access the list of all a user's friends. That means going through Facebook's App Review process which can be quite challenging (and annoying.)
Frankly, I am not even sure that it is possible to use the new Open Graph API to get the user's entire friend list.
I have an iPhone app that is used for taking photos. I just finished adding the Facebook sharing functionality to this app.
I went through this entire page here: https://developers.facebook.com/docs/ios/open-graph
I followed all of the instructions, and copied and pasted the code into xcode. The only thing I didn't do was the one part at the very bottom of the page called "Deep Linking", but that is not important right now.
After doing all of this, my app can successfully share an image to facebook. However, it is not being shared the way I need it to.
When I go to my facebook page to see the share, you would never even know it's there. I have to scroll almost half way down the page, and then it's in the bottom left corner.
Here is a screenshot showing where the share is located on my facebook page when viewed on a Desktop computer:
And here is how the share looks when using the Facebook App for the iPhone (I blacked out my name):
These both look terrible. Here are 2 examples of what I want to accomplish.
Here is how a photo from this app called "Frontback" looks when I share it to my page and view on a Desktop computer:
And it looks the same on the Facebook App for the iPhone as well.
The only difference I can tell is that the URL for my shares has "/activity/" in it, where as the Frontback app shares have "photo.php" in their Facebook URL's.
I can't figure out how to get my app's shares to look like the shares from the Frontback app.
Any help is greatly appreciated thank you.
The posts that you created seems meaningful to me. An open-graph feed is always beautiful and more meaningful than the normal feed.
What Frontback post you are seeing is simple photo upload, that's not a feed. I mean it all depends on your requirement, what exactly your app will want to do.
If you just want to show some photos via your app like Frontback, you can avoid open graph and publish photos using the API \POST /photos.
But if you want to give a link that could redirect the user to the app you should use what you are using right now.
Another thing, when you said-
When I go to my facebook page to see the share, you would never even know it's there. I have to scroll almost half way down the page, and then it's in the bottom left corner.
That's the beauty of open-graph, it clubs all the activities of an app in your timeline, not unnecessarily making status updates and flooding your timeline. The stories appear on top in your/your friends wall and the ticker. You can also see the actual story by clicking on the time in the story of your activity log-
(activity log)
(actual story)
- (void)requestPermissionAndPost {
[FBSession.activeSession requestNewPublishPermissions:[NSArray arrayWithObjects:#"publish_actions", #"publish_checkins",nil]
defaultAudience:FBSessionDefaultAudienceEveryone
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
// Now have the permission
[self postOpenGraphAction];
} else {
// Facebook SDK * error handling *
// if the operation is not user cancelled
if (error.fberrorCategory != FBErrorCategoryUserCancelled) {
[self presentAlertForError:error];
}
}
}];
}
- (void)postOpenGraphAction
{
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];
};
UIImage *img = imageView.image;
NSString *message = [NSString stringWithFormat:#"%# %# #DealsHype",msg.text,hashtagFromStore];
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];
}
this is the good to upload image with some message .. if you want to upload a big image like Frontback
I want to get the app user ID for Facebook, as described here:
https://developers.facebook.com/docs/ads-for-apps/custom-audiences-for-mobile-apps/
The code snippet they give is:
[FBRequestConnection startForCustomAudienceThirdPartyID:nil
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSString *id = error ? nil : [result objectForKey:#"custom_audience_third_party_id"];
// Stash off this id, send it to your server, etc. Use later to construct
// a custom audience. A result of 'nil' means that either the user can't be
// identified, or they've limited ad tracking via iOS 6.
}
];
This always returns error 400 for me. Answers like this suggest that it needs to be used as part of a larger piece of code but there's no mention of this on the Facebook page.
Can I just use the snippet above, or do I need to implement something around it?
I got this from the FB developer page:
Discussion:
This method will thrown an exception if either <[FBSettings defaultAppID]> or <[FBSettings clientToken]> are nil. The appID won't be nil when the pList includes the appID, or if it's explicitly set. The clientToken needs to be set via <[FBSettings setClientToken:]>.
.....
Please check the conditions above first. Ass per documentation
startForCustomAudienceThirdPartyID: -> should actually point to the current FBSession
Right after the session is created do this: [FBSession setActiveSession:session];
Answered here: Facebook iOS SDK 3.1: "Error: HTTP status code: 400"
I'm using the iOS SDK with the native dialog to try to post an object and action.
When I call presentShareDialogWithOpenGraphAction, the Facebook app opens, briefly shows the dialog with my post in it, and then returns to my app with the error:
Could not generate preview text
My code looks like this:
NSDictionary* object = #{
#"fbsdk:create_object": #YES,
#"type": #"appsterbator.app_idea",
#"title": #"test",
#"url": #"http://test.com",
};
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
[action setObject:object
forKey:#"app_idea"];
[FBDialogs presentShareDialogWithOpenGraphAction:action actionType:#"app_idea.create"
previewPropertyName:#"app_idea"
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
NSLog(#"%#", error);
}];
Also, is it possible post an Open Graph object that doesn't actually have a URL?
I had the same symptoms, but a different fix. Facebook SDK 3.5.* since the Share Dialog came out of beta.
I had a custom Object Graph story: Solve -> Puzzle. This was my first time working with OG, so this might seem obvious to someone more familiar with it, but it stalled me for long enough that I wanted to share.
I ran through the Share Dialog examples on the developer site, but the Open Graph related sharing would not work via simple copy paste. I figured because the OG objects were tied to the App ID and URL host etc. I setup my web host so that I could serve OG data for my objects, and configured my app to allow that host etc..
So I set about adapting the sample code to use the parameters present in the "opengraph / stories -> Get Code" popover. Setting the platform to iOS SDK, I got the following for Create Action:
NSMutableDictionary<FBGraphObject> *action = [FBGraphObject graphObject];
action[#"puzzle"] = #"http://samples.ogp.me/463417983744195";
[FBRequestConnection startForPostWithGraphPath:#"me/shapeshuffle:solve"
graphObject:action
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
// handle the result
}];
I swapped my story and app specific values into the sample code, leading to the the error and symptoms described in the question.
I spent longer than I care to admit fiddling with the server hosting my OG object, FB App settings, different ways of popping the share dialog etc.
The root of the problem was that on popping the dialog, FB was unable to match the action and object with the configuration in my app - hence the slightly vague error code relating to generating the preview text. FB wasn't finding the action because "me/shapeshuffle:solve" (the action string in the "Get Code" tool) doesn't resolve. If I understood all the different options available to me in the Get Code tool, I might have avoided this, but remember, all I wanted was to pop a share dialog. Seemed simple.
I worked with the Graph API explorer via this useful tutorial, and wound up with the following mapping from the strings I got from the FB tool to what actually worked:
Action:
me/shapeshuffle:solve => shapeshuffle:solve
Lots of pain for 3 little characters. Here is what my finished code looks like:
NSString *objectUrl = [NSString stringWithFormat:#"%#puzzleId=%d", #"http://myhost.com/puzzle/object?", puzzleId];
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
[action setObject:objectUrl forKey:#"puzzle"];
[action setObject:timeString forKey:#"time"];
[FBDialogs presentShareDialogWithOpenGraphAction:action
actionType:#"shapeshuffle:solve"
previewPropertyName:#"puzzle"
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
Had the same issue. Make sure the App Domains in Basic Info contains the oAuth domain. The odd thing I found is that in order to add this you need to enable this can only be added if you enable Page Tab or Mobile Web or one of the other options.
I think i may know the reason that (#"url": #"http://test.com")->this may use the facebook app developer center offer.
click Open Graph
click Stories
then you will see your custom story on right side
click Get Code,then you will get the URL you need!
and (#"type": #"appsterbator.app_idea")->this may need use like this->(your_app_namespace:action_type)
Good luck!
To problem with: "Could not generate preview text" come from attempts to share the same content several times.
Try to change content that you share each time you check the functionality of open graph.
A condition that causes this which has not been described yet is case sensitivity of the action and property name, which must be lowercase. To illustrate note the 'must_be_lowercase' in the following:
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
[action setObject:#"http://link/" forKey:#"**must_be_lowercase**"];
[FBDialogs presentShareDialogWithOpenGraphAction:action
actionType:#"xxxx"
previewPropertyName:#"**must_be_lowercase**"
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
This is a lovely generic error message! Another possible cause I've encountered is the size of the OpenGraph image being posted.
Although Facebook documentation states images must be 200x200px to 1500x1500px, my initial attempts with a 350x350px image failed with the “Could not generate preview text” error. The same image at 600x600px on the other hand works perfectly.
-James
Now I've got simple request to Facebook api:
me/feed?fields=type,story,caption,message,picture,comments&limit=20&offset=0
It works fine, but in the comments section, there are message, name and user id who post this comment, but I also need a photo-link. Of course I can send more requests to get user-photo. But I think it would be silly decision. Maybe there is way to send fql or batch request to get all fields I need in one request?
P.S. I already know how to do it with ruby, but i need some example which I can use in ios app.
Edit: Also I've got simple example, which do a little more detailed listing, but also without photo. What I should add to request2, to get photo?
JSFacebookRequest *request1 = [JSFacebookRequest requestWithGraphPath:#"me/feed? fields=story,message,comments&offset=15&limit=5"];
[request1 setName:#"get-field"];
JSFacebookRequest *request2 = [JSFacebookRequest requestWithGraphPath:#"?ids={result=get-field:$.data..id}"];
[facebook fetchRequests:[NSArray arrayWithObjects:request1, request2, nil] onSuccess:^(NSArray *responseObjects) {
NSLog(#"Responses:\n%#", responseObjects);
} onError:^(NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
Perhaps I'm misunderstanding your situation, but it seems to me that you're over-complicating things. If you've got the user id, you can build the needed URL like so:
https://graph.facebook.com/<user_id>/picture
If that doesn't give you the desired image size, there are other options listed here. (See the 'images' parameter, for example.)