I need to publish Open Graph story to Facebook wall from my app. I followed current tutorial on Facebook developers.
I've created object,action and story on Facebook dashboard. Then in my app do the following code:
create an object:
NSMutableDictionary<FBOpenGraphObject> *object = [FBGraphObject openGraphObjectForPost];
object.provisionedForPost = YES;
object[#"title"] = #"test title";
object[#"type"] = #"myapp:my_object_type";
object[#"description"] = #"test discription";
object[#"url"] = #"http://example.com";
object[#"image"] = #[#{#"url": [result objectForKey:#"uri"], #"user_generated" : #"false" }];
and post it:
[FBRequestConnection startForPostOpenGraphObject:object completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error) {
NSString *objectId = [result objectForKey:#"id"];
NSLog(#"object id %#",objectId);
} else {
NSLog(#"Error posting the Open Graph object to the Object API: %#", error);
}
}];
} else {
NSLog(#"Error staging an image: %#", error);
}
}];
Got object id as result.
Then create an action and link it with object:
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
[action setObject:objectId forKey:#"my_object_type"];
FBOpenGraphActionParams *params = [[FBOpenGraphActionParams alloc] init];
params.action = action;
params.actionType = #"myapp:my_app_action";
And post it to Facebook:
[FBRequestConnection startForPostWithGraphPath:#"/me/myapp:my_app_action" graphObject:action completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error) {
NSLog(#"OG story posted, story id: %#", [result objectForKey:#"id"]);
[[[UIAlertView alloc] initWithTitle:#"OG story posted"
message:#"Check your Facebook profile or activity log to see the story."
delegate:self
cancelButtonTitle:#"OK!"
otherButtonTitles:nil] show];
} else {
NSLog(#"Encountered an error posting to Open Graph: %#", error);
}
}];
As a result i got the message that OG story was successfully posted, but when going to Facebook, there is nothing in feed or timeline, just an image added to users photo album.
Well, dunno what was the problem, but now it works with the following code:
FBRequestConnection *connection = [[FBRequestConnection alloc]init];
NSMutableDictionary <FBOpenGraphObject> *object = [FBGraphObject openGraphObjectForPost];
object[#"type"] = #"myapp:my_object_type";
object[#"title"] = #"title";
object[#"url"] = #"http://example.com";
object[#"image"] = #"http://image.png";
object[#"description"] = #"description";
FBRequest *objectRequest = [FBRequest requestForPostOpenGraphObject:object];
[connection addRequest:objectRequest completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (error) {
NSLog(#"Error: %#",error.description);
}
} batchEntryName:#"objectCreate"];
NSMutableDictionary <FBOpenGraphAction> *action = [FBGraphObject openGraphActionForPost];
action[#"buy"] = #"{result=objectCreate:$.id}";
action[#"fb:explicitly_shared"] = #"true";
FBRequest *actionRequest = [FBRequest requestForPostWithGraphPath:#"me/myapp:my_app_action" graphObject:action];
[connection addRequest:actionRequest completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (error) {
NSLog(#"error: %#",error.description);
} else {
NSLog(#"posted with id %#", result[#"id"]);
}
}];
[connection start];
Related
I am trying to get Facebook friend list with name, id, etc in my app.
- (IBAction)onFBLogin:(id)sender {
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login
logInWithReadPermissions: #[#"public_profile", #"email", #"user_friends"]
fromViewController:self
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(#"Process error");
} else if (result.isCancelled) {
NSLog(#"Cancelled");
} else {
NSLog(#"%#", result);
[self getFBEmailAddress];
}
}];
}
-(void)getFBEmailAddress{
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me"
parameters:#{#"fields": #"picture, email, friends"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSString *pictureURL = [NSString stringWithFormat:#"%#",[result objectForKey:#"picture"]];
mFBId = [NSString stringWithFormat:#"%#",[result objectForKey:#"id"]];
NSLog(#"My Profile : %#", result);
NSLog(#"email is %#", [result objectForKey:#"email"]);
[self getFBFriendList];
}
else{
NSLog(#"%#", [error localizedDescription]);
}
}];
}
-(void)getFBFriendList{
NSString* graphPat = [[NSString alloc] initWithFormat:#"%#/friends", mFBId];
FBSDKGraphRequest *requestFriends = [[FBSDKGraphRequest alloc]
initWithGraphPath:graphPat
parameters:#{#"fields": #"id, name"}
HTTPMethod:#"GET"];
[requestFriends startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if (!error && result)
{
NSArray *allFriendsResultData = [result objectForKey:#"data"];
if ([allFriendsResultData count] > 0)
{
for (NSDictionary *friendObject in allFriendsResultData)
{
NSString *friendName = [friendObject objectForKey:#"name"];
NSString *friendID = [friendObject objectForKey:#"id"];
NSLog(#"%# : %#", friendID, friendName);
}
}
}
}];}
I've succeed to login via Facebook and get my profile. After that, I've tried to get friend list via the friends graph api. But at that time, it only said count of friends following as below.
friends = {
data = (
);
summary = {
"total_count" = 2;
};
};
id = 60XXXXXX1295X;
picture = {
data = {
"is_silhouette" = 0;
url = "https://scontent.xx.fbcdn.net/hprofile-xfa1/v/t1.0-1/p50x50/1..._501957533...";
};
};
How Can I get full information of friends list such as id, name, etc? Please help me if any one already implemented. Thank you.
This work for me.
NSMutableArray *completeList = [[NSMutableArray alloc] init];
[self fetchFacebookEachFriend:completeList withGrapPath:#"/me/friends" withCallback:^(BOOL success, NSMutableArray * fbList) {
//Finish get All Friends
fbListFinal(success, fbList);
}];
- (void)fetchFacebookEachFriend:(NSMutableArray *)completeList withGrapPath:(NSString *)graphPath withCallback:(returnFbList)fbList
{
NSDictionary *limitDictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"first_name, last_name, middle_name, name, email", #"fields", nil];
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:limitDictionary HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (error) {
[[[UIAlertView alloc] initWithTitle:#"Alert!" message:#"Please connect to Facebook to find your friends" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
fbList(NO, completeList);
return;
}
//Add each friend to list
for (NSDictionary *friend in [result valueForKey:#"data"]) {
[completeList addObject:friend];
}
if ([result valueForKey:#"paging"] != nil && [[result valueForKey:#"paging"] valueForKey:#"next"] != nil) {
NSString *nextPage = [[result valueForKey:#"paging"] valueForKey:#"next"];
nextPage = [[nextPage componentsSeparatedByString:#"?"] objectAtIndex:1];
[self fetchFacebookEachFriend:completeList withGrapPath:[NSString stringWithFormat:#"me/friends?%#",nextPage] withCallback:fbList];
} else
fbList(YES, completeList);
}];
}
result.paging.next contains the complete URL, with access token and all. I find the simplest thing is just to pass it on to an NSURLSession data task:
NSString *nextPage = result[#"paging"][#"next"];
if (!nextPage) return;
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:nextPage] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
id json = [self decodeJSONResult:data response:response error:error];
// use json
}] resume];
I wrote this as an FBSDKGraphRequest extension: FBSDKGraphRequest+Paging.h
I would like to share a custom story by Facebook SDK for iOS. I tried to do it in these ways, but none of them works:
Does not log anything
[FBGraphObject openGraphObjectForPostWithType:#"Lorem ipsum"
title:#"Lorem ipsum"
image:#"https://example.com/cooking-app/images/Lamb-Vindaloo.png"
url:#"https://example.com/cooking-app/meal/Lamb-Vindaloo.html"
description:#"Spicy curry of lamb and potatoes"];
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
[action setObject:cell.params forKey:slugs[self.categoryID]];
[FBDialogs presentShareDialogWithOpenGraphAction:action
actionType:[NSString stringWithFormat:#"Lorem ipsum:%#", slugs[self.categoryID]]
previewPropertyName:slugs[self.categoryID]
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
The operation couldn't be completed. (com.facebook.sdk error 5.)
[FBSession openActiveSessionWithAllowLoginUI:NO];
FBRequest *request = [FBRequest requestForPostWithGraphPath:#"/me/Lorem ipsum" graphObject:#{#"object": cell.params}];
[request setHTTPMethod:#"POST"];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
if (!error)
{
// Sucess! Include your code to handle the results here
NSLog(#"result: %#", result);
NSString *alertTitle = #"Object successfully created";
NSString *alertText = #"An object has been created";
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertText
delegate:self
cancelButtonTitle:#"OK!"
otherButtonTitles:nil] show];
}
else
{
NSLog(#"%#", [error localizedDescription]);
}
}];
cell.params
cell.params = [FBGraphObject openGraphObjectForPostWithType:[NSString stringWithFormat:#"Lorem ipsum:%#", slugs[self.categoryID]]
title:#"Lorem ipsum"
image:[NSString stringWithFormat:#"https://example.com/cooking-app/images/%#.png", slugs[self.categoryID]]
url:#"https://example.com"
description:#"Lorem ipsum"];
cell.params[#"Lorem ipsum"] = #{#"minutes": #5, #"seconds": #37, #"hours": #1};
I wrote code as below where file exists in resources. Its not null.
I am successful in adding images, but stuck at videos.
-(void)uploadVideo {
NSLog(#"UPload Videio ");
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"abc" ofType:#"mp4"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingUncached error:&error];
if(data == nil && error!=nil) {
//Print error description
NSLog(#"error is %#", [error description]);
}
NSLog(#"data is %#", data);
NSDictionary *parameters = [NSDictionary dictionaryWithObject:data forKey:#"sample.mov"];
if (FBSession.activeSession.isOpen) {
[FBRequestConnection startWithGraphPath:#"me/videos"
parameters:parameters
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// [FBRequestConnection setVideoMode:NO];
if(!error) {
NSLog(#"OK: %#", result);
} else
NSLog(#"Error: %#", error.localizedDescription);
}];
} else {
// We don't have an active session in this app, so lets open a new
// facebook session with the appropriate permissions!
// Firstly, construct a permission array.
// you can find more "permissions strings" at http://developers.facebook.com/docs/authentication/permissions/
// In this example, we will just request a publish_stream which is required to publish status or photos.
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"publish_stream",
nil];
//[self controlStatusUsable:NO];
// OPEN Session!
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// if login fails for any reason, we alert
if (error) {
// show error to user.
} else if (FB_ISSESSIONOPENWITHSTATE(status)) {
// no error, so we proceed with requesting user details of current facebook session.
[FBRequestConnection startWithGraphPath:#"me/videos"
parameters:parameters
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// [FBRequestConnection setVideoMode:NO];
if(!error) {
NSLog(#"Result: %#", result);
} else
NSLog(#"ERROR: %#", error.localizedDescription);
}];
//[self promptUserWithAccountNameForUploadPhoto];
}
// [self controlStatusUsable:YES];
}];
}
}
In return I am getting error as
The operation couldn’t be completed. (com.facebook.sdk error 5.)
How to upload video to facebook using facebook iOS SDK?
Thanks
Here's a method to upload video to Facebook. This code is testing and 100% working.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Specify App ID and permissions
NSDictionary *options = #{ACFacebookAppIdKey: FACEBOOK_ID,
ACFacebookPermissionsKey: #[#"publish_stream", #"video_upload"],
ACFacebookAudienceKey: ACFacebookAudienceFriends}; // basic read permissions
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accountsArray = [accountStore accountsWithAccountType:facebookAccountType];
if ([accountsArray count] > 0) {
ACAccount *facebookAccount = [accountsArray objectAtIndex:0];
NSDictionary *parameters = #{#"description": aMessage};
SLRequest *facebookRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString:#"https://graph.facebook.com/me/videos"]
parameters:parameters];
[facebookRequest addMultipartData: aVideo
withName:#"source"
type:#"video/mp4"
filename:#"video.mov"];
facebookRequest.account = facebookAccount;
[facebookRequest performRequestWithHandler:^(NSData* responseData, NSHTTPURLResponse* urlResponse, NSError* error) {
if (error == nil) {
NSLog(#"responedata:%#", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
}else{
NSLog(#"%#",error.description);
}
}];
}
} else {
NSLog(#"Access Denied");
NSLog(#"[%#]",[e localizedDescription]);
}
}];
Recommendation:
I think this might be a permissions issue but I am not sure where the error is being thrown. The delegate method that would be thrown is not shown in your code. I think reconciling your code with the steps in this sample might be helpful; if so please accept the answer.
Some key aspects of the sample:
Permissions:
- (IBAction)buttonClicked:(id)sender {
NSArray* permissions = [[NSArray alloc] initWithObjects:
#"publish_stream", nil];
[facebook authorize:permissions delegate:self];
[permissions release];
}
Build Request:
- (void)fbDidLogin {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"mov"];
NSData *videoData = [NSData dataWithContentsOfFile:filePath];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
videoData, #"video.mov",
#"video/quicktime", #"contentType",
#"Video Test Title", #"title",
#"Video Test Description", #"description",
nil];
[facebook requestWithGraphPath:#"me/videos"
andParams:params
andHttpMethod:#"POST"
andDelegate:self];
}
Request didLoad delegate method:
- (void)request:(FBRequest *)request didLoad:(id)result {
if ([result isKindOfClass:[NSArray class]]) {
result = [result objectAtIndex:0];
}
NSLog(#"Result of API call: %#", result);
}
Request didFail delegate method:
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
NSLog(#"Failed with error: %#", [error localizedDescription]);
}
Facebook Video Permissions Link
This Code is Tested successfully On FaceBook SDK 3.14.1
Recommendation: In .plist
set FacebookAppID,FacebookDisplayName,
URL types->Item 0->URL Schemes set to facebookappId prefix with fb
-(void)shareOnFaceBook
{
//sample_video.mov is the name of file
NSString *filePathOfVideo = [[NSBundle mainBundle] pathForResource:#"sample_video" ofType:#"mov"];
NSLog(#"Path Of Video is %#", filePathOfVideo);
NSData *videoData = [NSData dataWithContentsOfFile:filePathOfVideo];
//you can use dataWithContentsOfURL if you have a Url of video file
//NSData *videoData = [NSData dataWithContentsOfURL:shareURL];
//NSLog(#"data is :%#",videoData);
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
videoData, #"video.mov",
#"video/quicktime", #"contentType",
#"Video name ", #"name",
#"description of Video", #"description",
nil];
if (FBSession.activeSession.isOpen)
{
[FBRequestConnection startWithGraphPath:#"me/videos"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error)
{
NSLog(#"RESULT: %#", result);
[self throwAlertWithTitle:#"Success" message:#"Video uploaded"];
}
else
{
NSLog(#"ERROR: %#", error.localizedDescription);
[self throwAlertWithTitle:#"Denied" message:#"Try Again"];
}
}];
}
else
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"publish_actions",
nil];
// OPEN Session!
[FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (error)
{
NSLog(#"Login fail :%#",error);
}
else if (FB_ISSESSIONOPENWITHSTATE(status))
{
[FBRequestConnection startWithGraphPath:#"me/videos"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error)
{
[self throwAlertWithTitle:#"Success" message:#"Video uploaded"];
NSLog(#"RESULT: %#", result);
}
else
{
[self throwAlertWithTitle:#"Denied" message:#"Try Again"];
NSLog(#"ERROR: %#", error.localizedDescription);
}
}];
}
}];
}
}
And I GOT Error:
The operation couldn’t be completed. (com.facebook.sdk error 5.)
It happens when facebook is being inited. Next time i open my app, it works fine, its always the first time. Tried everything in app, but it seems to be on the Facebook SDK side.
Few causes for seeing com.facebook.sdk error 5:
Session is is not open. Validate.
Facebook has detected that you're spamming the system. Change video name.
Facebook has a defined limit using the SDK. Try a different app.
Did you ask for a publish_stream permission before?
Is it possible to use the Facebook SDK or Graph API to create a post like the one below?
I essentially want to combine these two together:
[FBRequestConnection startForUploadPhoto:[UIImage imageNamed:#"myImage"] completionHandler:nil];
[FBRequestConnection startForPostStatusUpdate:#"Hello, World!" completionHandler:nil];
Thanks.
Use following method :
// Present share dialog
[FBDialogs presentShareDialogWithLink:params.link
name:params.name
caption:params.caption
description:params.description
picture:params.picture
clientState:nil
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);
}
}];
Here is the reference : https://developers.facebook.com/docs/ios/share
Try this,
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:UIImagePNGRepresentation(_image) forKey:#"picture"];
if (message) {
[dictionary setObject:message forKey:#"message"];
}
FBRequest *request = [FBRequest requestWithGraphPath:#"me/photos" parameters:dictionary HTTPMethod:#"POST"];
[connection addRequest:request completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
}];
[connection start];
I'm uploading a photo as an open graph object, then tying it into my open graph action once it returns the URL.
Everything is working great so far, but I'm not able to get the custom user message "TEST TEST TEST TEST!" to show up. I've been hitting this issue from all angles and can't seem to get it nailed down. Any ideas?
- (void)postPhotoThenOpenGraphAction {
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
// First request uploads the photo.
FBRequest *request1 = [FBRequest requestForUploadPhoto:[UIImage imageWithData:[NSData dataWithContentsOfFile:picture.pathSmall]]];
[connection addRequest:request1 completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
} else {
[self showFacebookFailedError];
}
}
batchEntryName:#"photopost"];
// Second request retrieves photo information for just-created
// photo so we can grab its source.
FBRequest *request2 = [FBRequest requestForGraphPath:#"{result=photopost:$.id}"];
[connection addRequest:request2 completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error && result) {
NSString *source = [result objectForKey:#"source"];
[self postOpenGraphActionWithPhotoURL:source];
} else {
[self showFacebookFailedError];
}
}
];
[connection start];
}
- (void)postOpenGraphActionWithPhotoURL:(NSString*)photoURL {
id<PTOGPicture> photoGraphObject = [self pictureObjectForPicture:self.picture];
id<PTOGSharePicture> action = (id<PTOGSharePicture>)[FBGraphObject graphObject];
action.photo = photoGraphObject;
if (self.selectedPlace) {
action.place = self.selectedPlace;
}
if (self.selectedFriends.count > 0) {
action.tags = self.selectedFriends;
}
action.message = #"TEST TEST TEST TEST!";
if (photoURL) {
NSMutableDictionary *image = [[NSMutableDictionary alloc] init];
[image setObject:photoURL forKey:#"url"];
NSMutableArray *images = [[NSMutableArray alloc] init];
[images addObject:image];
action.image = images;
}
// Create the request and post the action to the.
[FBRequestConnection startForPostWithGraphPath:#"me/myappapp:share"
graphObject:action
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
//... code taken out for brevity
}];
}
I have a simpler version that works for what you want:
First you create your action object as you wish:
- (void)shareOnFacebook {
NSMutableDictionary<FBGraphObject> *action = [FBGraphObject graphObject];
action[#"<OPEN_GRAPH_OBJ>"] = obj;
action[#"image[0][url]"] = url;
action[#"image[0][user_generated]"] = #"true";
action[#"message"] = #"some message here";
[FBRequestConnection startForPostWithGraphPath:#"me/<app_namespace>:<action>" graphObject:action completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
}];
}
However, the requirement for this to work, is that you must have these two permissions set on the action setup page:
I hope it helps.