What I am trying to do and it doesn't work is the following: post an image of my choise and also an url to facebook using the built in facebook sharer, the problem is that it doesn't work to upload both, it's either picture + text and works nice or url + text and works nice, but when I combine them text+picture+url it gets the picture from the url and not my uploaded pic. Any suggestions? I am doing this on iOS9
UIImage *tableViewScreenshot = [tblFeed screenshotOfCellAtIndexPath:idx];
SLComposeViewController *fbSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[fbSheet setInitialText:#"I need your vote"];
[fbSheet addURL:[NSURL URLWithString:str]];
[fbSheet addImage:tableViewScreenshot];
The problem is that Facebook has changed some policies and by this you can't have a text or an image present as a default. That's why you're not seeing the text and photo. Here are 2 scenarios one with Facebook app installed and another one without Facebook app installed. The below one is when the Facebook app is already installed on the device.
And this one is when the Facebook app is not installed on the device
And this is my code:
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controller addURL:[NSURL URLWithString:#"https://www.google.com"]];
[controller addImage:[UIImage imageNamed:#"icon_circle"]];
[controller setInitialText:#"Bhavuk you're great!"];
[self presentViewController:controller animated:YES completion:nil];
So If you want to share everything, better use FB SDK.
So it seems at the moment there is no solution for this and we should find a workaround for it, maybe uploading everything first a picture to an url and then use fb sdk to point to a picture from that url + the link as an offline pic doesn't seem to work unfortunately.
Unfortunately, the problem remains even on iOS 10. An easy workaround is simply drop the URL, for example:
SLComposeViewController *fbSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[fbSheet setInitialText:#"I need your vote"];
[fbSheet addImage:tableViewScreenshot];
It's not a direct answer to the OP but in case of what you only care is showing text and image while sharing something, here is a possible solution:
If the image and the text that you want to show within your SlComposeView is the same as the information that exist within the web site that you are going to share; you don't need to do anything special at the iOS side at all.
If you are the one who also created the web page that you're sharing URL of, should you have proper Open Graph META Tags at the page, SLComposeView of type Facebook will show image and text which were set at the webpage within your app automagically.
For some information about Facebook Open Graph Markup; see https://developers.facebook.com/docs/sharing/webmasters/#markup
I have had facebook sharing working fine in my ios app when fb not install. and i have installed fb to use the latest api (4.7.x) and now sharing doesnt work at all. I check that I have publish_actions permission (which I do prior to this method being called, I have 'expicitly shared' checked in open graph settings, action types, capabilities. I am validating the content (I dont get an error) and have a delegate, none of its methods get called.
-(void)shareWithFacebook:(NSString *)message
{
if ([[FBSDKAccessToken currentAccessToken] hasGranted:#"publish_actions"])
{
NIDINFO(#"Facebook sharing has publish_actions permission");
}
else
{
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logInWithPublishPermissions:#[#"publish_actions"]
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
NIDERROR(#"Facebook sharing getting publish_actions permission failed: %#", error);
}
];
}
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary: #{
#"og:type": #"article",
#"og:title": #"Bloc",
#"og:description": message,
#"og:url": #"http://getonbloc.com/download"
}];
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
// Create the action
FBSDKShareOpenGraphAction *action = [FBSDKShareOpenGraphAction actionWithType:#"mynamespace:Share" object:object key:#"article"];
[action setString:#"true" forKey:#"fb:explicitly_shared"];
// Create the content
FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init];
content.action = action;
content.previewPropertyName = #"article";
// Share the content
FBSDKShareAPI *shareAPI = [[FBSDKShareAPI alloc] init];
shareAPI.shareContent = content;
shareAPI.delegate = self;
NSError *error;
if([shareAPI validateWithError:&error] == NO)
{
NIDERROR(#"Facebook sharing content failed: %#", error);
}
[shareAPI share];
}
#pragma mark - FBSDKSharingDelegate
- (void) sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NIDINFO(#"Facebook sharing completed: %#", results);
}
- (void) sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error
{
NIDERROR(#"Facebook sharing failed: %#", error);
}
- (void) sharerDidCancel:(id<FBSDKSharing>)sharer
{
NIDINFO(#"Facebook sharing cancelled.");
}
Related
I have had facebook sharing working fine in my ios app for a year and have upgraded (aka totally rewritten) to use the latest api (4.7.x) and now sharing doesnt work at all. I check that I have publish_actions permission (which I do prior to this method being called, I have 'expicitly shared' checked in open graph settings, action types, capabilities. I am validating the content (I dont get an error) and have a delegate, none of its methods get called.
-(void)shareWithFacebook:(NSString *)message
{
if ([[FBSDKAccessToken currentAccessToken] hasGranted:#"publish_actions"])
{
NIDINFO(#"Facebook sharing has publish_actions permission");
}
else
{
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logInWithPublishPermissions:#[#"publish_actions"]
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
NIDERROR(#"Facebook sharing getting publish_actions permission failed: %#", error);
}
];
}
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary: #{
#"og:type": #"article",
#"og:title": #"Bloc",
#"og:description": message,
#"og:url": #"http://getonbloc.com/download"
}];
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
// Create the action
FBSDKShareOpenGraphAction *action = [FBSDKShareOpenGraphAction actionWithType:#"mynamespace:Share" object:object key:#"article"];
[action setString:#"true" forKey:#"fb:explicitly_shared"];
// Create the content
FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init];
content.action = action;
content.previewPropertyName = #"article";
// Share the content
FBSDKShareAPI *shareAPI = [[FBSDKShareAPI alloc] init];
shareAPI.shareContent = content;
shareAPI.delegate = self;
NSError *error;
if([shareAPI validateWithError:&error] == NO)
{
NIDERROR(#"Facebook sharing content failed: %#", error);
}
[shareAPI share];
}
#pragma mark - FBSDKSharingDelegate
- (void) sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NIDINFO(#"Facebook sharing completed: %#", results);
}
- (void) sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error
{
NIDERROR(#"Facebook sharing failed: %#", error);
}
- (void) sharerDidCancel:(id<FBSDKSharing>)sharer
{
NIDINFO(#"Facebook sharing cancelled.");
}
I have login working and can get photos fine. I don't get any feedback at all from the facebook api, nothing gets posted. Am I doing something particularly stupid here?
Just a possibility, but I find that Facebook integration has become inconvenient because I find that every time I check the current token for granted permission through hasGranted:, it almost always fail even though I gained permission a few minutes ago, or from a previous app launch.
It seems that in your code, if no permission is granted, you try to login and get the permission again. But when that block returns, regardless whether the actual permission is granted or not, you throw an error. Instead, you should continue with sharing if it is successful.
Is there such feature that can be un-locked when the user shares my app via Facebook or Tweeter?
Like this:
1) The user clicks on "Share" button within my app
2) My app is then posted(shared or advertised) on the wall of the user's facebook
3) Some feature gets unlocked within my app
You can use the Facebook sharing delegate method to know whether the user has successfully shared OR not.
Below is FB developer link which show various sharing methods,according to your requirements.
https://developers.facebook.com/docs/sharing/ios
Below are the methods in which you can know the sharing status
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results{
//UNLOCK THE APP FEATURE IN THIS METHOD
}
- (void)sharerDidCancel:(id<FBSDKSharing>)sharer{
}
- (void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error{
NSLog(#"%#",error);
}
See iOS Facebook Tutorial for an example of how its done on the facebook end.
On the app side you can setup a flag on NSUserDefaults or write to the app filesystem to check if the feature is unlocked.
This can be done relatively painlessly using UIActivityViewController and its completion handler.
NSString *message = #"my app is awesome.";
NSURL *link = [NSURL URLWithString:#"awesomeapp.com"];
UIActivityViewController *shareController = [[UIActivityViewController alloc] initWithActivityItems:#[message, link]
applicationActivities:nil];
//add whatever you don't want
shareController.excludedActivityTypes = #[UIActivityTypeMessage];
shareController.completionWithItemsHandler =
^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
//Share wasn't completed, don't unlock
if (!completed || activityError) {
return;
}
//Facebook or Twitter
if ([activityType isEqualToString:UIActivityTypePostToFacebook] ||
[activityType isEqualToString:UIActivityTypePostToTwitter]) {
//Unlock item logic
}
};
[self presentViewController:shareController animated:YES completion:^{
//Whatever
}];
After updating to iOS 8.3 the text is not inserted into the share dialog
i use a standard
UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:applicationActivities];
NSArray *excludeActivities = #[UIActivityTypeAssignToContact];
vc.excludedActivityTypes = excludeActivities;
if (IsUserInterfaceIdiomPad) {
vc.popoverPresentationController.sourceView = self.navigationController.view;
}
[self.navigationController presentViewController:vc animated:YES completion:^{
}];
where the items are a NSString and an NSURL
Looks like Facebook doesn't want the app to pre-propagate the share dialog with text anymore :(
It doesn't have to do anything with the iOS version, but with the build in Facebook App (as the share processes is somehow interlinked with the FB app)
It's stupid and on Android you couldn't do it either (it was disabled longer ago) i hope Facebook reconsiders this as it will lead to fewer shares and some might be willing to drop the share option
Note: if the user doesn't have the FB app installed (he removed it), than the text is added to the status, but i guess that only a small amount of users, but maybe a good reason to still supply text to the share items
NSString *strName= #"Mohit Thatai";
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login
logInWithReadPermissions: #[#"public_profile", #"email"]
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error)
{
NSLog(#"Process error");
}
else if (result.isCancelled)
{
NSLog(#"Cancelled");
}
else
{
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
[content setContentTitle:#"GPS Tracker"];
[content setContentDescription:[NSString stringWithFormat:#"%# shared an interesting link\n This might be interesting to you: GPS Tracker for Kids",strName]];
content.contentURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://gpsphonetrackerkids.com"]];
[FBSDKShareDialog showFromViewController:self
withContent:content
delegate:nil];
}
}];
I am trying to set up Facebook sharing with FBSDK in my iOS app.
I have been reading the documentation here, and currently have
[FBSDKShareDialog showFromViewController:self withContent:content delegate:self];
working with a content object - FBSDKShareLinkContent.
However, upon trying to use the similar method as specified for Facebook Messenger sharing,
[FBSDKMessageDialog showWithContent:content delegate:self];
i am getting a crash. I caught the error and logged it in one of the delegate methods, and it states "The operation couldn’t be completed. (com.facebook.sdk.share error 202.)
"
I have searched for this specific error but have not found anything directly with the same error. Here is full code
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = [NSURL URLWithString:kAPPShareLink];
content.contentDescription = kAPPShareDescription;
content.contentTitle = kAPPShareTitle;
if (buttonIndex == 0) {
// Facebook
[FBSDKShareDialog showFromViewController:self withContent:content delegate:self];
} else if (buttonIndex == 1) {
// Facebook Messenger
[FBSDKMessageDialog showWithContent:content delegate:self];
}
Forgive me if i am missing something obvious, but as this documentation reads, i assume the FBSDKMessageDialog showWithContent: method would work the same way as FBSDKShareDialog showFromViewController: which is working for me.
I am using the latest version of XCode with iOS8.
I had to login and then Post , that is how it worked :
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
if (error)
{
// Process error
}
else if (result.isCancelled)
{
// Handle cancellations
}
else
{
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = [NSURL URLWithString:#"https://developers.facebook.com/"];
FBSDKMessageDialog *messageDialog = [[FBSDKMessageDialog alloc] init];
messageDialog.delegate = self;
[messageDialog setShareContent:content];
if ([messageDialog canShow])
{
[messageDialog show];
}
else
{
// Messenger isn't installed. Redirect the person to the App Store.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"https://itunes.apple.com/en/app/facebook-messenger/id454638411?mt=8"]];
}
}
}];
and the Share Delegate :
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSLog(#"didCompleteWithResults");
}
- (void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError ::: %#" , error);
}
- (void)sharerDidCancel:(id<FBSDKSharing>)sharer
{
NSLog(#"sharerDidCancel");
}
Edit:
[messageDialog canShow] returns NO on the iPad, works fine on iPhone
Posted the issue on Facebook Developers forum.
I was stuck with this for a while and in the end realised that I had not added fb-messenger-share-api under LSApplicationQueriesSchemes in the info.plist file. Just putting this here in case it helps someone. Thanks :)
N.B. It is fb-messenger-share-api and not fb-messenger-api.
Note: This fits more as a comment, but I don't have enough reputation yet to post comments
I get the same error, both Facebook and messenger are updated.
I checked my permissions with
[[FBSDKAccessToken currentAccessToken] permissions]
and I think I have enough:
"contact_email",
"publish_stream",
"user_likes",
"publish_checkins",
"video_upload",
"create_note",
"basic_info",
"publish_actions",
"public_profile",
"photo_upload",
"status_update",
email,
"user_friends",
"share_item"
I tried the same way as OP, and also I tried that:
FBSDKMessageDialog *messageDialog = [[FBSDKMessageDialog alloc] init];
[messageDialog setShareContent:content];
messageDialog.delegate = self;
if ([messageDialog canShow]) {
[messageDialog show];
}
[messageDialog canShow] returns NO, and the delegate methods catch the fail with the 202 error described by the OP.
I tried using the FBSDKSendButton, and doesn't seem to work either.
On the other hand, FBSDKShareDialog works perfectly...
I hope this helps to solve the issue.
This bubbled up again in an interweb search. Nowadays, there is a simple answer for the error Message dialog is not available with code 202:
Facebook's documentation:
Note: Currently the message dialog is not supported on iPads.
I'm trying to share using Twitter Framework on iOS 5
The user will select which account to use, so the app will share using the account selected.
But whem share pass to performRequestWithHandler nothing happen an the error return null
My code:
for (int i = 0; i < [_accountsArray count]; i++) {
//searching for a selected account
if ([[[_accountsArray objectAtIndex:i] username] isEqualToString:[self getUserName]]) {
actualUser = [_accountsArray objectAtIndex:i];
TWRequest *sendTweet = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"]
parameters:nil
requestMethod:TWRequestMethodPOST];
[sendTweet addMultiPartData:[text dataUsingEncoding:NSUTF8StringEncoding] withName:#"status" type:#"multipart/form-data"];
ACAccountStore *account = [[ACAccountStore alloc] init];
[sendTweet setAccount:[account.accounts objectAtIndex:i]];
NSLog(#"%#",sendTweet.account);
[sendTweet performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"responseData: %#\n", responseData);
NSLog(#"urlResponse: %#\n", urlResponse);
NSLog(#"error: %#",error);
}];
}
}
anyone can help me?
Thanks
Sending tweets in iOS is extremely easy now. Last night I updated my app to no longer use the old technique and instead use the new SLComposeViewController technique. Below is a snippet of code I have in my application that allows the user send a tweet with the attached image. Basically the exact same code can be used to post to facebook. Try using this code instead. It should also allow the user to choose what account they send the tweet from (I also believe this "default account" sending setting is buried in the settings of the phone someplace).
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
SLComposeViewController *mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[mySLComposerSheet setInitialText:#"Sample Tweet Text"];
//Add the image the user is working with
[mySLComposerSheet addImage:self.workingImage];
//Add a URL if desired
//[mySLComposerSheet addURL:[NSURL URLWithString:#"http://google.com"]];
//Pop up the post to the user so they can edit and submit
[self presentViewController:mySLComposerSheet animated:YES completion:nil];
//Handle the event
[mySLComposerSheet setCompletionHandler:^(SLComposeViewControllerResult result) {
switch (result) {
case SLComposeViewControllerResultCancelled:
NSLog(#"Tweet Canceled");
case SLComposeViewControllerResultDone:
NSLog(#"Tweet Done");
break;
default:
break;
}
}];
} else {
//Can't send tweets, show error
NSLog(#"User doesn't have twitter setup");
}