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.
Related
Hi I have recently started coding for iOS.I am trying to get videos from facebook using the following code.
-(void)facebookGetVideos:(UIViewController*)vc completionHandler:(void (^)(NSMutableArray*))completionBlock{
__block NSMutableArray * itemArray;
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"me/videos/uploaded"
parameters:#{#"fields":#"source,description,thumbnail,title"}
HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if(error!=nil){
NSLog(#"Error after fb dwnld %#",error);
[MBProgressHUD hideHUDForView:vc.view animated:true];
[self showAlert:#"Error" message:error.localizedDescription viewController:vc];
}else{
NSLog(#"Results %#",result);
itemArray = [[NSMutableArray alloc]init];
// [itemArray addObject:[result valueForKey:#"data"]];
itemArray =[result valueForKey:#"data"];
completionBlock(itemArray);
}
}];
}
The response I am getting from there is as below:-
{
data = (
{
id = 1845903302379295;
source = "https://video.xx.fbcdn.net/v/t43.1792-2/27475816_220074475216744_8742438766032977920_n.mp4?efg=eyJybHIiOjE1MDAsInJsYSI6MTAyNCwidmVuY29kZV90YWciOiJzdmVfaGQifQ%3D%3D&rl=1500&vabr=382&oh=d4c3f6028a979c5919fdd8e444e24179&oe=5A89882A";
},
{
id = 1814936632142629;
source = "https://video.xx.fbcdn.net/v/t42.14539-2/23925286_2650490725061654_2502749796398268416_n.mp4?efg=eyJybHIiOjU3NiwicmxhIjo1MTIsInZlbmNvZGVfdGFnIjoic2QifQ%3D%3D&rl=576&vabr=320&oh=2fde1aea6eff33d8139ccb8fe7a33fd4&oe=5A8980C0";
}
);
paging = {
cursors = {
after = MTgxNDkzNjYzMjE0MjYyOQZDZD;
before = MTg0NTkwMzMwMjM3OTI5NQZDZD;
};
};
}
I am trying to use this after before as parameters as below:-
-(void)afterValues:(NSString*)afterVal{
NSDictionary * parameters =#{#"fields":#"source",#"after": afterVal};
FBSDKGraphRequest *request1 = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"me/videos/uploaded"
parameters:parameters
HTTPMethod:#"GET"];
[request1 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
NSLog(#"after videos%#",result);
}];
}
And getting the following as response:-
after videos{
data = (
);
}
Can anyone please point out at my mistake.Any kind of help/suggestion or guidance in this directions would be highly appreciated.Thanks in advance!
Have you requested the manage_pages permission from the respective user through the login dialog? I think you see an empty result because of the missing permission.
UIImage *image = [UIImage imageNamed:#"attachment_blank.png"];
FBSDKSharePhoto *photo = [FBSDKSharePhoto photoWithImage:image userGenerated:NO];
NSDictionary *properties = #{
#"og:type": #"app:recipe",
#"og:title": #"Sample Recipe",
#"og:description": #"",
#"og:url": #"http://samples.ogp.me/216213502062059",
#"og:image": #[photo]
};
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
FBSDKShareAPI *shareAPI = [[FBSDKShareAPI alloc] init];
[shareAPI createOpenGraphObject:object];
The submission guidelines speak about a "user generated photos" permission that doesn't seem to be available anywhere in the app settings, or anywhere else in the documentation. Is that still required? Is there a similar permission for images?
You can try this method to share an image with link. The image you want to share should need to be on server(i.e. you need to use link of an image )
Note:- You must have an "publish_actions" permission from facebook app
Below method is shown using the facebook sdk 4.3
In .h file
#import <FacebookSDK/FacebookSDK.h>
#property (strong, nonatomic) FBRequestConnection *requestConnection;
In .m file
-(IBAction)facebookBtn:(id)sender{
if (!FBSession.activeSession.isOpen) {
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile", #"email", #"user_events", #"user_location", #"publish_actions"]
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
if (error)
{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:NSLocalizedString(#"Error", nil) message:error.localizedDescription delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
if (error.code!=2)
{
[alertView show];
}
}
else if (session.isOpen)
{
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[self requestCompleted:connection forFbID:#"me" result:result error:error];
}];
// create the connection object
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
// create a handler block to handle the results of the request for fbid's profile
FBRequestHandler handler =
^(FBRequestConnection *connection, id result, NSError *error) {
// output the results of the request
[self requestCompleted:connection forFbID:#"me" result:result error:error];
[self showAlert:NSLocalizedString(#"Posted successfully", nil)];
};
// 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
NSString *messageString=[NSString stringWithFormat:NSLocalizedString(#"Just parked at %# with #ParkHero", nil),#"miami"];
NSString *imageUrl = #"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFoE4FjiykSb-3usYJ6OuyUsa_NB0s0B13u52IKK80se0qOwPJ" ;
// Your facebook application link
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"https://www.facebook.com/ParkHero?fref=ts", #"link",imageUrl, #"picture",messageString,#"message",nil];
FBRequest *request=[[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:#"me/feed" parameters:params 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];
}
}];
}
else
{
FBRequestConnection *newConnection = [[FBRequestConnection alloc] init];
// create a handler block to handle the results of the request for fbid's profile
FBRequestHandler handler = ^(FBRequestConnection *connection, id result, NSError *error) {
// output the results of the request
[self requestCompleted:connection forFbID:#"me" result:result error:error];
[self showAlert:NSLocalizedString(#"Posted successfully", nil)];
};
// 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
NSString *messageString=[NSString stringWithFormat:NSLocalizedString(#"Just parked at %# with #ParkHero", nil),#"miami"];
NSString *imageUrl = #"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFoE4FjiykSb-3usYJ6OuyUsa_NB0s0B13u52IKK80se0qOwPJ";
// Your facebook application link
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"https://www.facebook.com/ParkHero?fref=ts", #"link",imageUrl, #"picture",messageString,#"message",nil];
FBRequest *request=[[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:#"me/feed" parameters:params 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];
}
}
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];
Is it possible to create multiple Picture albums dynamically in Facebook through objective C, so that we have text definition for album, every time we upload certain pictures ?
The current code, we are using is as follows :
for (UIView *view in scrollView.subviews)
{
if (view.tag == IMAGE_VIEW_TAG) {
NSData *attachmentData = [self getImageData:view];
UIImage *img = [UIImage imageWithData:attachmentData];
FBRequest *photoUploadRequest = [FBRequest requestForUploadPhoto:img];
[photoUploadRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
}];
NSLog(#"This is Image");
}
if (view.tag == TEXT_VIEW_TAG)
{
NSString *message = #""
message = [self getTextData:view];
NSLog(#"mesage values %#",message);
NSMutableDictionary* params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:message, #"message",nil];
[FBRequest startWithGraphPath:#"me/feed" parameters:params HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error){
I am having some trouble trying to get the Facebook iOS SDK to batch upload photos. Currently I can upload them one by one, but I would like to batch the requests if possible. I have read this post over and over along with the fb batch docs. Here is what I have thus far.
Facebook *facebook = [(AppDelegate*)[[UIApplication sharedApplication] delegate] facebook];
NSData *imageData = UIImagePNGRepresentation([imgs objectAtIndex:0]);
NSString *jsonRequest1 = [NSString stringWithFormat:#"{ \"method\": \"POST\", \"relative_url\": \"me/photos\", \"attached_files\": \"file1\" }"];
NSString *jsonRequest2 = [NSString stringWithFormat:#"{ \"method\": \"POST\", \"relative_url\": \"me/photos\", \"attached_files\": \"file2\" }"];
NSString *jsonRequestsArray = [NSString stringWithFormat:#"[ %#, %# ]", jsonRequest1, jsonRequest2];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:jsonRequestsArray,#"batch",imageData,#"file1",imageData,#"file2" nil];
I am mapping the imageData to the key it is looking for, but I get this response every time.
{
body = "{\"error\":{\"message\":\"File batch has not been attached\",\"type\":\"GraphBatchException\"}}";
code = 400;
headers = (
{
name = "WWW-Authenticate";
value = "OAuth \"Facebook Platform\" \"invalid_request\" \"File batch has not been attached\"";
},
{
name = "HTTP/1.1";
value = "400 Bad Request";
},
{
name = "Cache-Control";
value = "no-store";
},
{
name = "Content-Type";
value = "text/javascript; charset=UTF-8";
}
);
},
{
body = "{\"error\":{\"message\":\"File file2 has not been attached\",\"type\":\"GraphBatchException\"}}";
code = 400;
headers = (
{
name = "WWW-Authenticate";
value = "OAuth \"Facebook Platform\" \"invalid_request\" \"File file2 has not been attached\"";
},
{
name = "HTTP/1.1";
value = "400 Bad Request";
},
{
name = "Cache-Control";
value = "no-store";
},
{
name = "Content-Type";
value = "text/javascript; charset=UTF-8";
}
);
}
)
Any help is very much appreciated.
Have you tried using the Social framework for iOS 6 to share photos? It allows you to add all the photos and share them.
- (IBAction)postToFacebook:(id)sender {
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controller setInitialText:#"First post from my iPhone app"];
[controller addURL:[NSURL URLWithString:#"http://www.jinibot.com"]];
[controller addImage:[UIImage imageNamed:#"socialsharing-facebook-image.jpg"]];
//add as many images as you want
[controller addImage:[UIImage imageNamed:#"socialsharing-facebook-image.jpg"]];
[controller addImage:[UIImage imageNamed:#"socialsharing-facebook-image.jpg"]];
[controller addImage:[UIImage imageNamed:#"socialsharing-facebook-image.jpg"]];
[self presentViewController:controller animated:YES completion:Nil];
}
}
Try with this.
Please notice that Facebook limit the number of requests which can be in a batch to 50.
-(void)uploadBulkPhotosToAlbum:(NSArray *)photoArray albumId:(NSString *)albumId
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
NSString *graphPath = [NSString stringWithFormat:#"%#/photos",albumId];
NSMutableString *jsonFormat = [[NSMutableString alloc] init];
[jsonFormat setString:#"["];
for (int i = 0; i < photoArray.count; i++)
{
if (i != 0)
{
[jsonFormat appendString:#","];
}
NSString *fileName = [NSString stringWithFormat:#"file%d",i];
NSString *jsonRequest = [NSString stringWithFormat:#"{ \"method\": \"POST\", \"relative_url\": \"%#\", \"attached_files\": \"%#\" }",graphPath,fileName];
[jsonFormat appendString:[NSString stringWithFormat:#" %#",jsonRequest]];
}
[jsonFormat appendString:#" ]"];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:jsonFormat,#"batch",nil];
for (int i = 0; i < photoArray.count; i++)
{
NSString *fileName = [NSString stringWithFormat:#"file%d",i];
NSData *data = UIImagePNGRepresentation([photoArray objectAtIndex:i]);
[params setObject:data forKey:fileName];
}
FBRequest *request = [FBRequest requestWithGraphPath:#"me" parameters:params HTTPMethod:#"POST"];
[connection addRequest:request completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error)
{
[self resetViewAfterUpload:result];
}
else
{
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
NSLog(#"Photo uploaded failed :( %#",error.userInfo);
[[[UIAlertView alloc] initWithTitle:#"Error occurred!!" message:#"Some error occured while uploading." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil] show];
}
}];
[connection start];
}
With the new Facebook SDK (3.0) try something like this:
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
FBRequest *request1 = [FBRequest requestForUploadPhoto:image1];
[connection addRequest:request1
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
//handle error/success
}
];
FBRequest *request2 = [FBRequest requestForUploadPhoto:image2];
[connection addRequest:request2
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
//handle error/success
}
];
[connection start];
How about using an NSOperationQueue to queue up all the upload requests?
Here is function I have used in one of our project by Facebook SDK 3.x
-(void)postOnFacebookWall : (id )response{
NSString *strPost = [NSString stringWithFormat:#"Group Name:%#",[[response valueForKey:#"GroupDetail"] valueForKey:#"group_name"]];
NSString *strUrl = [NSString stringWithFormat:#"%#",[[response valueForKey:#"GroupDetail"] valueForKey:#"group_picture_path"]];
NSURL *urlToShare = [NSURL URLWithString:strUrl];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:urlToShare]];
FBAppCall *appCall = [FBDialogs presentShareDialogWithLink:urlToShare
name:#"Heook"
caption:#"string"
description:#"The 'Has."
picture:urlToShare
clientState:nil
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if (error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
if (!appCall) {
// Next try to post using Facebook's iOS6 integration
BOOL displayedNativeDialog = [FBDialogs presentOSIntegratedShareDialogModallyFrom:self
initialText:strPost
image:image
url:nil
handler:nil];
if (!displayedNativeDialog) {
[self performPublishAction:^{
// NSString *message = [NSString stringWithFormat:#"Group Name:%#\nGroup Image:%#\n",[[response valueForKey:#"GroupDetail"] valueForKey:#"group_name"],[[response valueForKey:#"GroupDetail"] valueForKey:#"group_picture_path"]];
[FBRequestConnection startForPostStatusUpdate:strPost
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[self showAlert:#"Group shared on facebook" result:result error:error];
}];
}];
}
}
}