Facebook Integration and data fetching not working - ios

I have used the following code to fetch data from the Facebook to my app.
I have did all the other stuff in app delegate and plist.
This sometimes works and fetched data and sometimes don't. Can anyone help me with this. I can't figure what the problem is!
- (IBAction)facebook:(id)sender
{
FBLoginView *loginView=[[FBLoginView alloc]init];
loginView.delegate=self;
loginView.readPermissions = #[#"first_name",
#"last_name",
#"location",
#"id",
#"access_token"];
NSArray* permissions = [NSArray arrayWithObjects: #"email", nil];
loginView.readPermissions=permissions;
[FBSession openActiveSessionWithAllowLoginUI:YES];
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user1,
NSError *error) {
if (!error) {
firstname=user1.first_name;
lastname=user1.last_name;
city=[user1.location objectForKey:#"name"];
email=user1[#"email"];
fbid=user1.id;
Loggedin=#"Y";
[[NSUserDefaults standardUserDefaults]setObject:Loggedin forKey:#"token"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
if (![fbid isEqualToString:#""])
{
[self performSegueWithIdentifier: #"Facebooksegue" sender: self];
}
NSLog(#"%#",firstname);
NSLog(#"%#",lastname);
NSLog(#"%#",city);
NSLog(#"%#",email);
NSLog(#"%#",fbid);
}];
}
My AppDelegate
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBSession class];
return YES;
}

I had a similar situation and I had used almost the same code as you did.
My problem was with the test Facebook id which I had used. I hadn't had it verified so it didn't respond with the email. Try using another account and it might work. If not check whether your app is authorized with the Facebook account synchronized with your account in the settings.
Hope this helps.

Go to the blue project icon at the top left, select your target, go to build settings, find other linker flags, add -ObjC. This will make it so that the entire framework gets statically linked and thus you can reference FBLoginView in the storyboard successfully.

Related

Can we add or use handleOpenURL other app delegate

I'm building SDK for my product and there will be no app delegate class. I used Dropbox Integration in my SDK, so I'm bound to use following method.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSString *stringUrl = [url absoluteString];
if ([stringUrl containsString:#"cancel"]) {
// Handle if user cancelled the login
[[NSNotificationCenter defaultCenter] postNotificationName:#"dropboxRegistrationCancel" object:self];
return NO;
}
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
[[NSNotificationCenter defaultCenter] postNotificationName:ApplicationComeBackFromDropBoxLoginPage object:self];
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
So Issue is there is no app delegate than how can use above method?
Or any alternate solution for this to use this in another class (like to inherit UIResponder class).
Looking for help.
If you are building a SDK with no appDelegate, then well, you have nothing to do. It will be in your project where you will be using your sdk that you will have to add this line.
By the way, the line NSString *stringUrl = [url absoluteString]; is absolutly useless since you are not using stringUrl later on, and the
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// NSString *stringUrl = [url absoluteString];
return YES;
}
just means: yes you can quit my app to open another app when the user click on a link.
No biggy....

'user' is always nil in logInInBackgroundWithReadPermissions in Parse iOS SDK

I'm using Facebook SDK with Parse SDK in user Login.
Using 'logInInBackgroundWithReadPermissions' to perform login, Even though user is authenticated the app, 'user' is always nil in the response. And error is:
Error Domain=com.facebook.sdk.login Code=304 "The operation couldn’t
be completed. (com.facebook.sdk.login error 304.)"
Here is my Implementation:
• Basic configuration:
I have configured every thing in .plist
and followed guidelines at link1, link2
• Imported frameworks:
• Implementation in Appdelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[Parse setApplicationId:#"I have used real key here" clientKey:#"I have used real key here"];
[PFFacebookUtils initializeFacebookWithApplicationLaunchOptions:launchOptions];
return YES; }
- (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 {
[FBSDKAppEvents activateApp];
}
• Login Implementation:
NSArray *fbPermissions = [[NSArray alloc] initWithObjects: #"public_profile", nil];
[PFFacebookUtils logInInBackgroundWithReadPermissions:fbPermissions block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
}
else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
} else {
NSLog(#"User logged in through Facebook!");
}
}];
But in the call back, 'user' is always nil. Did anyone face the same issue?
- Thanks in advance.
I was not able to find out cause for the issue. But I just deleted all frameworks related to Parse and Facebook and Re-added all of them. It worked fine. So, there is no issue in the code.
in AppDelegate.m file, under didFinishLaunchingWithOptions method, initialize Parse before initializing PFFacebookUtils.

FBSDKSharingDelegate callback not working, even when post works fine

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.

Trouble verifying Facebook publish_actions permission

I have successfully logged into Facebook and asked for publish_actions permission. The permission is granted, as I can readily verify on https://www.facebook.com/settings?tab=applications and also by calling
-(void) whatPermissionsDoIHave
{
[FBRequestConnection startWithGraphPath:#"/me/permissions"
completionHandler:^(
FBRequestConnection *connection,
NSDictionary* result,
NSError *error
) {
//do checks in here
}
}];
}
So I know for certain that I have permission. However, whenever it's time to share, my permission check returns false. I will now show my permission check
+ (BOOL)hasWritePermissions
{
if (!FBSession.activeSession.isOpen) return NO;
NSLog(#"So the session is at least open");
return [FBSession.activeSession.permissions indexOfObject:#[#"publish_actions"]] != NSNotFound;
}
So am I missing something else? Perhaps something I should have done in AppDelegate or such? Thanks for any insight.
Right now the only call I am making in AppDelegate is
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
fallbackHandler:^(FBAppCall *call) {
NSLog(#"In fallback handler");
}];
}
The permissions property is an array of strings, but you're calling indexOfObject on another array, which is probably why it can't find it. Try this instead:
return [FBSession.activeSession.permissions indexOfObject:#"publish_actions"] != NSNotFound;

Scringo and Parse: how to perform simultaneous Facebook login?

My app allows typical registration (e-mail,username,password, etc), but also enables Facebook/Twitter signup/singin via Parse. If at all possible, I'd like to avoid forcing a user to sign in twice if they sign in with Facebook or Twitter. Currently, I've added "Scringo's" programmatic signup capability to sign users into "scringo" with the same credentials they use for my app; however. What if they sign up with Facebook? It seems very confusing for a user to sign in with say, Facebook, and then slide a bar over, and to access the messaging component to be forced to login with Facebook again.
Here's what I have currently, is there anyway to link the Facebook/Twitter signin process so that both Parse gets the information along with Scringo in the press of one button?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Parse setApplicationId:#"...gzPI7Omoxc..."
clientKey:#"...s22ZqIbM7n..."];
[PFTwitterUtils
initializeWithConsumerKey:#"...W4XjjpHz..."
consumerSecret:#"...Czjtht7v5..."];
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
[PFFacebookUtils initializeFacebook];
[self configureNavigationBar];
[Scringo initWithAppId:#"...N2cCMhW1Bv..." completion:^{
[Scringo addSidebar:self.window toLeft:YES];
PFUser *currentUser = [PFUser currentUser];
if (! [ScringoUser currentUser].isAuthenticated) {
[ScringoUser signUpWithEmail:currentUser.email userName:currentUser.username password:#"notforyou" completion:^(ScringoUser *aUser, BOOL isSuccess) {
if (isSuccess) {
[currentUser setObject:aUser.userId forKey:#"ScringoUserId"];
[currentUser saveInBackground];
}
}];
}
}];
return YES;
}
Turns out there is a method in the SDK (I simply overlooked it)
[Scringo connectFacebook]
If the app has successfully logged into facebook already, calling this authenticates Scringo as well.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Parse setApplicationId:#"gzPI7OmoxcSYqQGWASjzVd8lP5q8FVJqh2ZLsXnp"
clientKey:#"s22ZqIbM7n8SN1End57vmTmmeL55YnIen7dmMhIR"];
[PFTwitterUtils
initializeWithConsumerKey:#"W4XjjpHzG03bWK8R0iPvs27Yy"
consumerSecret:#"Czjtht7v58yfZ00QV5Gkumfdy8RauCyPllYh5SPm00I3M6fkPP"];
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
[PFFacebookUtils initializeFacebook];
[self configureNavigationBar];
[Scringo initWithAppId:#"cvOV3lLwQN2cCMhW1BvnW2eWnyoiLNgA" completion:^{
[Scringo addSidebar:self.window toLeft:YES];
PFUser *currentUser = [PFUser currentUser];
if (! [ScringoUser currentUser].isAuthenticated) {
if (currentUser) {
if (currentUser.email) [Scringo connectFacebook];
else
[ScringoUser signUpWithEmail:currentUser.email userName:currentUser.username password:#"notforyou" completion:^(ScringoUser *aUser, BOOL isSuccess) {
if (isSuccess) {
[currentUser setObject:aUser.userId forKey:#"ScringoUserId"];
[currentUser saveInBackground];
}
}];
}
}
}];
return YES;
}
That's assuming a PFUser already exists, so I also added the same call to the login page for users logging in with facebook for the first time
- (void)logInViewController:(PFLogInViewController *)logInController didLogInUser:(PFUser *)user {
[self dismissViewControllerAnimated:YES completion:^{
if (!self.currentUser.email) [Scringo connectFacebook];
}];
}
Tested and working.

Resources