For some reason I keep getting an error for the AppInvite Dialog...
After setting up the info.plist for iOS9 by the documentation, setting all Facebook's parameters on the project, I get the error method being called with: Error Domain=com.facebook.sdk.core Code=9 "(null)".
App link was made on Facebook's Hosting API.
- (void) appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didFailWithError:(NSError *)error{
NSLog(#"error: %#",error);
}
the method I use to invoke the dialog:
-(void)inviteFriends{
FBSDKAppInviteDialog* dia= [[FBSDKAppInviteDialog alloc] init];
if ([dia canShow])
{
FBSDKAppInviteContent *content =[[FBSDKAppInviteContent alloc] init];
content.appLinkURL = [NSURL URLWithString:self.applink];
content.appInvitePreviewImageURL = [NSURL URLWithString:self.preview_image];
[FBSDKAppInviteDialog showFromViewController:self.rootViewController.mainViewController withContent:content delegate:self];
}
[dia release];
return;
}
I tried calling inviteFriends in different places, but it won't start and would get to the didFailWithError method.
However, for some reason it may start working all of a sudden, and would work all the time ever since, unless the app is deleted from the device and reinstalled. In this case, it won't open again...
Make sure you have [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; in your AppDelegate. I've spend two days while trying to fix that.
Also make sure you have [FBSDKAppEvents activateApp];
in applicationDidBecomeActive:(UIApplication *)application
Related
I have a share button with following code:
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = [NSURL fileURLWithPath:appFile];
FBSDKShareButton *shareButton = [[FBSDKShareButton alloc] init];
shareButton.shareContent = content;
shareButton.center = CGPointMake(60, 60);
And I see that my share button is greyed out. So I check my access token, which returns null:
NSString *fbAccessToken = [FBSDKAccessToken currentAccessToken].tokenString;
NSLog(#"fbAccessToken %#", fbAccessToken);
According to here, I need to call this first (I have implemented it inside my AppDelegate's - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions:
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions]
However, it returns NO, and according to FB's doc:
#abstract Call this method from the [UIApplicationDelegate
application:didFinishLaunchingWithOptions:] method of the AppDelegate
for your app. It should be invoked for the proper use of the Facebook
SDK.
#return YES if the url was intended for the Facebook SDK, NO if not.
I wonder why it returns NO that, perhaps, results my accessToken to be nil. Anyone can give me advise?
UPDATE:
I have logged-in, gained the token, allowed the permissions from my logged-in FB account, but the button is still greyed out.
For Android people need the native Facebook for Android app installed, version 7.0 or higher
Maybe it's the same thing on iOS.
FBSDKSharingDelegate callback is not working. I can post to facebook fine with the ios SDK, but I'd like to detect if the post was successful and take additional action to notify the user. However, the callback is not working for me. The delegate methods are not being called and I don't know why.
Using ios8, Parse as my backend. In Parse, the user is linked to FB. I'm using the IOS simulator.
What I've tried:
I've ensured that publish permissions are granted, saved, and linked to the Parse user. I've run a check and "publish_actions" are detected OK. The posting works fine as I can see the post on the facebook account. It's just the callback that is not working. I've checked my fb setup and it looks fine. For good measure at the very bottom I've included that relevant code from my app delegate. I've blocked out confidential keys with XXXX.
Code:
1st: See if user is logged in to Parse, if not, send to sign in and link to facebook account. Once that is done, I request "publish" permissions and link that additional permission to the Parse user. I know this works b/c when I recompile, it remembers the "publish" permissions and goes right to into the post.
#interface FacebookAPIPost () <FBSDKSharingDelegate>
#end
#implementation FacebookAPIPost
-(void)shareSegmentFacebookAPI { //if statement below
//1) logged in?, if not send to sign up screen
//2) else if logged in, link account to facebook account, then send post
//3) else send to post b/c signed up and linked already.
PFUser *currentUser = [PFUser currentUser];
if(!currentUser) {
[self pushToSignIn];
} else if(![PFFacebookUtils isLinkedWithUser:currentUser]){
[self linkUserToFacebook:currentUser];
NSLog(#"user account not linked to facebook");
} else {
[self shareSegmentWithFacebookComposer];
}
}
-(void)linkUserToFacebook:currentUser{
[PFFacebookUtils linkUserInBackground:currentUser withPublishPermissions:#[#"publish_actions"] block:^(BOOL succeeded, NSError *error) {
if(error){
NSLog(#"There was an issue linking your facebook account. Please try again.");
}
else {
NSLog(#"facebook account is linked");
//Send the facebook status update
[self shareSegmentWithFacebookComposer];
}
}];
}
-(void)shareSegmentWithFacebookComposer{
if ([[FBSDKAccessToken currentAccessToken] hasGranted:#"publish_actions"]) {
[self publishFBPost]; //publish
} else {
NSLog(#"no publish permissions"); // no publish permissions so get them, then post
[PFFacebookUtils linkUserInBackground:[PFUser currentUser]
withPublishPermissions:#[ #"publish_actions"]
block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"User now has read and publish permissions!");
[self publishFBPost];
}
}];
Here is where the post gets made:
-(void) publishFBPost{
FBSDKShareLinkContent *content = [FBSDKShareLinkContent new];
content.contentURL = [NSURL URLWithString:[self.selectedSegment valueForKey:#"linkToContent"]];
content.contentTitle = [self.selectedProgram valueForKey:#"programTitle"];
content.contentDescription = [self.selectedSegment valueForKey:#"purposeSummary"];
PFFile *theImage = [self.selectedSegment valueForKey:#"segmentImage"];
NSString *urlString = theImage.url;
NSURL *url = [NSURL URLWithString:urlString];
content.imageURL = url;
FBSDKShareDialog *shareDialog = [FBSDKShareDialog new];
[shareDialog setMode:FBSDKShareDialogModeAutomatic];
// [FBSDKShareDialog showFromViewController:self.messageTableViewController withContent:content delegate:self];
[shareDialog setShareContent:content];
[shareDialog setDelegate:self];
[shareDialog setFromViewController:self.messageTableViewController];
[shareDialog show];
}
Delegate methods below are not working. Meaning after the post is complete, I can see it on the FB account, but none of these delegate methods execute.
#pragma mark - delegate methods
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results {
// if ([sharer isEqual:self.shareDialog]) {
NSLog(#"I'm going to go crazy if this doesn't work.%#",results);
// Your delegate code
// }
}
- (void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error
{
NSLog(#"sharing error:%#", error);
NSString *message = error.userInfo[FBSDKErrorLocalizedDescriptionKey] ?:
#"There was a problem sharing, please try again later.";
NSString *title = error.userInfo[FBSDKErrorLocalizedTitleKey] ?: #"Oops!";
[[[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
- (void)sharerDidCancel:(id<FBSDKSharing>)sharer
{
NSLog(#"share cancelled");
}
Console output:
The only message I get back after posting is after a few seconds this message appears:
plugin com.apple.share.Facebook.post invalidated
Please help!
Footnote: appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize Parse.
[Parse enableLocalDatastore];
[Parse setApplicationId:#"XXXX"
clientKey:#"XXX"];
[PFFacebookUtils initializeFacebookWithApplicationLaunchOptions:launchOptions];
//Initialize Facebook
[FBSDKAppEvents activateApp];
return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
}
//Method added for facebook integration
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
[FBSDKAppEvents activateApp];
}
I think I am too late answering this question but someone else could trap into this as well, that's why sharing my knowledge.
As per Facebook API documentation
sharer:didCompleteWithResults: Sent to the delegate when the share completes without error or cancellation.
The results from the sharer. This may be nil or empty.
its probably because this delegate method is only get called when the post is successfully shared. In case of failure the other delegate method sharer:didFailWithError:get called. I think Facebook API should not need to add the result parameter is that case.
So in my experience if sharer:didCompleteWithResults whenever this is called that would mean success.
I have a little trouble when implementing new Facebook Login for our app. We are using Facebook SDK v4.3 for our development. And the login/signup process crashes on devices with low memory. We suspect that the low memory constraints have caused our app to terminate when it triggered a switch to Facebook for authentication. As document in the Facebook's old SDK (link https://developers.facebook.com/docs/facebook-login/ios#login-apicalls):
Login flows require an app switch to complete, it's possible your app gets terminated by iOS in low memory conditions or if your app does not support backgrounding.
In that case, the state change handler supplied to your open call disappears.
To handle that scenario explicitly assign a state change handler block to the FBSession instance any time prior to the handleOpenURL: call:
// During the Facebook login, your app passes control to the Facebook iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
// Note this handler block should be the exact same as the handler passed to any open calls.
[FBSession.activeSession setStateChangeHandler:^(FBSession *session, FBSessionState state, NSError *error) {
// Retrieve the app delegate
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
// Call the app delegate's sessionStateChanged:state:error method to handle session state changes
[appDelegate sessionStateChanged:session state:state error:error];
}];
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
}
Unfortunately, the new Facebook SDK deprecated FBSession.activeSession and its stateChangeHandler. I followed the custom UI FBLogin button for my app, here is my appDelegate code
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
The code works fine and executes perfectly under normal condition. However, it behave oddly under cold starts (due to low memory). So my question would be: How do we prevent this? Is there an equivalent handler for the new SDK?
PS. I did my job in managing the device's memory. But it still didn't work under this stressed conditions.
Edit: All I want is to grab the user's basic information on success. Therefore, I did not need keep track (or have the need to) of the access token. This is the block of code that I use to invoke login
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
[ErrorMessageDisplay displayErrorAlertOnViewController:self withTitle:FB_LOGIN_ERROR_TITLE andMessage:FB_LOGIN_ERROR_MESSAGE];
[self.loginView enableLoginButtons];
} else if (result.isCancelled) {
[ErrorMessageDisplay displayErrorAlertOnViewController:self withTitle:FB_LOGIN_CANCEL_TITLE andMessage:FB_LOGIN_CANCEL_MESSAGE];
[self.loginView enableLoginButtons];
} else {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:nil] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id user, NSError *error) {
//TODO do something in here
}];
}
}];
Using the part of the code, the app still freeze on low memory after authenticated using facebook. In fact, the handler did not get call at all
Make sure you follow all the steps in https://developers.facebook.com/docs/ios/getting-started including connecting the application:didFinishLaunchingWithOptions: of the FBSDKApplicationDelegate (in addition to the openURL:)
Check FBSDKAccessToken currentAccessToken in an appropriate area of your app (such as viewDidLoad, as described in https://developers.facebook.com/docs/facebook-login/ios/). This will be set for you by the SDK in cases of a "cold start" of your app.
I'm trying to use the Facebook iOS Sharing SDK 4.1 but not getting a post off. I have an active session, but the following code does not post to my feed, and I do not get any of the callbacks either (success, error, or cancel), even though the caller is a FBSDKSharingDelegate. I have attempted to emulate the sample code in the SDK documentation but to no avail.
if ( [[FBSDKAccessToken currentAccessToken] hasGranted:#"publish_actions"] ) {
FBSDKShareLinkContent* content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = _Object.myPostServerURL;
content.contentDescription = _Object.myPostDescription;
content.contentTitle = #"New Post";
content.imageURL = _Object.coverArtServerURL;
BOOL ok = [[FBSDKShareAPI shareWithContent:content delegate:self] share];
}
I've tried with and without the "share" message wrapped around the shareWithContent; I can't tell from the documentation if it is required. Either way, no callbacks to delegate, no post. Can someone help me?
FBSDKShareLinkContent *tempContent=[[FBSDKShareLinkContent alloc] init];
tempContent.contentTitle=#"hello";
tempContent.contentDescription=#"desc";
tempContent.imageURL=[NSURL URLWithString:#"https://camo.githubusercontent.com/67212912f8d2d6a474d1af756603f7c13c837112/687474703a2f2f692e696d6775722e636f6d2f375976386d53412e676966"];
tempContent.contentURL=[NSURL URLWithString:#"https://scrumptious-facebook.parseapp.com/meals/italian/?fb_action_ids=10200411040395078&fb_action_types=fb_sample_scrumps%3Aeat"];
_shareAPI.delegate = self;
_shareAPI.shareContent = tempContent;
[_shareAPI share];
Also to use FBSDKShareAPI,You have to implement your for login and request for necessary permissions through u get FBSDKAccessToken,then only u can directly post to user feed.This is according to documentation of Facebook,If u want to show your own interface of sharing.
Currently may be your delgate may not work but might be ur app may face the issues of no access tokens and no permission issues
[[[FBSDKLoginManager alloc] init]
logInWithPublishPermissions:#[publish_actions]
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if ([result.grantedPermissions containsObject:publish_actions]) {
[_shareAPI share];
} else {
// This would be a nice place to tell the user why publishing
// is valuable.
}
}];
//Delegate methods
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results{
}
- (void)sharerDidCancel:(id<FBSDKSharing>)sharer{
}
- (void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error{
NSLog(#"%#",error);
}
You have to make some configuration in your appdelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];}
and
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.}
In my iOS app i am trying to fetch details of a file stored in dropbox on click of button.
I am trying to choose a file from dropbox and redirect back to my application using DBChooser. It works fine when a user is already logged in the Dropbox.
-(void)choose{
[[DBChooser defaultChooser] openChooserForLinkType:DBChooserLinkTypeDirect fromViewController:self
completion:^(NSArray *results)
{
if ([results count]) {
_result = results[0];
link = [NSString stringWithFormat:#"%#", _result.link];
name = _result.name;
size = [NSString stringWithFormat:#"%lld", _result.size];
icon = [NSString stringWithFormat:#"%#", _result.iconURL];
} else {
_result = nil;
[[[UIAlertView alloc] initWithTitle:#"CANCELLED" message:#"user cancelled!"
delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil]
show];
}
}];
}
Also i have following function in Appdelegate.m
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:
(NSString *)sourceApplication annotation:(id)annotation
{
if ([[DBChooser defaultChooser] handleOpenURL:url]) {
// This was a Chooser response and handleOpenURL automatically ran the
// completion block
return YES;
}
return NO;
}
Problem starts when user is not logged in and when i click on button it opens dropbox and asks me to enter credentials. After successful logged in, i am able to view my dropbox data, but i am not able to choose anything i.e. on clicking an image it should redirect me back to my aplication, instead it is opening that image in dropbox itself. This happens only when user is not logged in.
I have set the URL schemes for the DropIns used for chooser. I just need to verify if user is logged in the dropbox before calling the choose function. Please help i am stuck on this.