FBSDK 4 iOS catch user logout - objective-c

I'm writing this app, that allows a user to login to my service either by registering first to my service, or use their Facebook, Instagram, etc login.
Now, if for some reason, a user has logged in to my app with FB, but decides to click the FB 'Logout' button, I want to offer the opportunity to login alternatively. For that I need to catch the Facebook Logout action.
So, the question is: how to trigger my "-(void)loginAlternatively" method? Where can I find a hook for that?
I tried to add
if (![FBSDKAccessToken currentAccessToken]) {
NSLog(#"Logged out of facebook");
}
to my AppDelegate's
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
since that is where I handle the post-login FB stuff. However, that doesn't seem to be the place.

It is just a matter of reading the documentation...
So:
Make the viewController a FBSDKLoginButtonDelegate
Add the *- (void)loginButtonDidLogOut:(FBSDKLoginButton )loginButton method to your .m file
Connect the button's delegate to the viewcontroller in the storyboard. (or declare myFBButton.delegate= self.)
Hope this helps others

Related

Unable to act on notification after app is killed

When my app is in foreground or inactive then upon receiving push notification, I can click on it and the desired action occurs. If I kill the app then upon tapping a notification the app comes to the home screen. Handling Push Notifications when App is Terminated from this post I understood that this is the desired behavior.
I also have 2 actionable buttons attached on my notification. if I click on one of them then I am not redirected to the home screen and the app loads indefinitely! Is there a work around to make the user come to the home screen?
Methods implemented by me which dont get executed after the app is killed and i receive a notification
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
Also, I read on the posts that after the app is killed and if I click on a notification then didFinishLaunchingWithOptions is executed. I added logger statement in my method but i dont receive them.
Any pointers are appreciated.

How to know if user like my page or dislike it using FBLikeControl?

I'm using Facebook Native Like button from FB-SDK.
When user click like button it redirect him to my Facebook page and ask him to like it or not , when user click on one of these two choice it redirect him to my app again and call
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
So I want to know if user click like,dislike,or back button ?
Is there is any way i can know that , like checking the like button text "like,Liked" ???
fbLikeControlView.likeControlStyle = FBLikeControlStyleButton;
fbLikeControlView.objectType=FBLikeControlObjectTypePage;
fbLikeControlView.objectID=currentLocation.facebook_page_url;
[fbLikeBtn addSubview:fbLikeControlView];

how to handle push notification if application is in inactive mode?

how do we handle push notification if app is in background mode? means i want to get push notification alert message when I am reopen the application after got the push notification alert.
can I do this ?
I am using this method when my my app is in active mode.
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
But when the app is not active, so how to get this?
You don't. Your app is not guaranteed to receive notifications. If the user taps the "open" button then your app will start with the dictionary passed in as the startup parameters in application:didFinishLaunchingWithOptions:. Of course, you users might tap cancel instead.
If the user taps the notification then only trigger to get the notification payload (or) userInfo dictionay value. which using below code in appdelegate file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
{
}
}

Native iOS Facebook SSO won't return to app

Ok this may seem like a duplicate but I've been through all of the questions that center around the issue and I still can't seem to get this to work for my app.
I have followed the iOS tutorial on the Facebook Developer site and I have done the following:
Created a Facebook App to get the Facebook App ID.
I've assigned this App ID to a constant and I use it to initialize the Facebook object within my app.
I've made sure my app is flagged for multitasking
I've setup the fbAPP_ID in the plist under the URLs drop down
I've made my AppDelegate a FBSessionDelegate and implemented very simple fbDidLogin and fbDidNotLogin delegate methods.
Versions: XCode 4.3.2 on Lion, iOS 5.1, Facebook iOS 4.1.1
All of this and I still can't seem to get Facebook to return control back to my app when it authorizes. It just stays in Facebook instead.
Code: (Note FB_APP_ID changed to basic number for viewing here)
AppDelegate.h:
#import <UIKit/UIKit.h>
#import "FBConnect.h"
#define FB_APP_ID #"1234567890"
#interface AppDelegate : UIResponder <UIApplicationDelegate, FBSessionDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) Facebook* facebook;
#end
AppDelegate.m:
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize facebook = _facebook;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_facebook = [[Facebook alloc] initWithAppId:FB_APP_ID andDelegate:self];
if (![_facebook isSessionValid])
{
[_facebook authorize:nil];
}
}
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL *)url
{
return [_facebook handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [_facebook handleOpenURL:url];
}
- (void)fbDidLogin
{
NSLog(#"App logged in");
}
- (void)fbDidNotLogin:(BOOL)cancelled
{
NSLog(#"App did not login");
}
#end
Relevant Info.plist porton:
Facebook App screen (mostly pinked out):
Note: I tried it with only basic settings and also with the iOS Native app settings with a fake iTunes store ID but the same bundle ID from my provisioning profile.
No matter what I do it always loads up Facebook and asks to authorize my app and then it simply closes the auth screen window and sits there on my Facebook screen instead of returning to my app.
Also note: I know it will always ask because I'm not checking for the auth token and expiration date.....that's the next step....for now I want to at least get it to return to my app before I worry about that.
Have I missed something here? Anything else I can try to get Facebook to return to my app?
EDIT: Also when debugging, I can't seem to find any spot where either openURL is called for some reason.
EDIT #2: When running it on the simulator, it loads up the FB Dialog via Safari (as expected) and then when I authorize, safari throws an error as if the URL they are trying to use to get back to my app is invalid:
This still doesn't tell me much since my fb1234567890 is setup right as far as I know in the Info.plist.
Your info.plist seems to be formatted incorrectly
Ensure that the url scheme is nested under an item (an array to be exact) called "URL Schemes"
This array should contain all possible URL Schemes that can launch your app
See the attached image for a better explanation of URL Schemes
Also, the "URL identifier" should be your bundle identifier: ex. com.mycompany.myapp
This should match the identifier you provide on your provisioning profiles
hope this helps!
All you have to follow these steps
STEP 1:
Facebook developer side stuff:
If your app is already submitted then fill iphone/ipad appstore id otherwise leave it empty.
STEP 2:
Next in your XCode:
Goto
Target > Info > URL Types > click plus icon and add the items like this-
In my application, there were both options to login via facebook and google so I created two URL Types. You can see second one are Facebook URL Type settings. URL Scheme will be your facebook app id from facebook Developer account with fb at starts. So if your facebook developer app id is 9876543267575645 then URL Scheme will become fb9876543267575645.
STEP 3:
Next, you have to add a new key in info.plist. So remain in same screen and add FacebookAppID like this screen:
All this stuff will bring your app back after successful facebook oauth.
STEP 4:
Rest you will do in your AppDelegate class. Simply add this method in AppDelegate.m
NSString *retURL = [NSString stringWithFormat:#"%#", url];
if ([retURL rangeOfString:facebookid].location != NSNotFound)
{
// if your application is coming back from facebook native app.
return [_facebook handleOpenURL:url];
}
else
{
// if your app is coming back from google plus oauth.
return [GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation];
}
during all this, must intialise and synthesize facebook instance in AppDelegate.m
#synthesize facebook = _facebook;
and didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_facebook = [[Facebook alloc] initWithAppId:facebookid];
// rest of your code is already here......
}
One more important thing. During I was implementing these steps, I also did too much research to achieve this and finally the working stuff is here. I made these settings in two of my apps.
But while I was creating third app, I started from beginning and did not follow STEP 1 and STEP 3 and voila.... redirection works! So i don't think facebook developer account Native iOS App settings are necessary while you are making Facebook login in your app..
I ran into another issue. I edited the raw Info.plist file and added:
<key>URL Types</key>
<array>
<dict>
<key>URL Schemes</key>
<array>
<string>fbxxxxxxxxx</string>
</array>
</dict>
</array>
That didn't work because the keys are not 'URL Types', 'URL Schemes' and 'URL Identifier', it's 'CFBundleURLTypes' , 'CFBundleURLSchemes' and 'CFBundleURLIdentifier' instead. Xcode will rename that in the editor to 'URL Types', 'URL Schemes' and 'URL Identifier'.
To be sure select the Info.plist in xcode, right click->show raw keys/values.
None of the above, or other answers on SO, worked for me, though I seemed to have the exact same issue.
However, when I enabled "Deep Linking", it worked perfectly, so it may have been a combination of all of the above AND enabling that option too.

How can I use a "Splash" UIViewController to conditionally redirect to another view controller?

I have a "Splash screen" ViewController extending UIViewController, set as the the initial app VC in my storyboard. This controller features a login form.
When the app starts, and before anything is displayed on the screen, I want this splash VC to check the user defaults to see if the user is already logged in. If so, I want the splash VC to redirect to the app's home VC, all before anything is displayed on the screen.
If the user is not logged in, I want the Splash VC to finish loading, displaying the login forms.
How would I go about implementing this? Would I place all of these checks in the init methods? I was having a hard time getting any code in the splash VC init methods to run at all, for some reason these methods don't get called.
Code in the viewDidLoad method runs fine, but running the code there would defeat the purpose of trying to allow the already-logged-in-user to start the app right into the home screen.
Suggestions? Thanks in advance.
My pick of the place to put this logic is in application didFinishLaunchingWithOptions: of application delegate. Here is how it would look :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
//////////////////////////////////////////////
// 1. do loading data etc.
// 2. check whether user is signed in or not
//////////////////////////////////////////////
if(already signed in)
{
dispatch_sync(dispatch_get_main_queue(), ^{
[self.window.rootViewController performSegueWithIdentifier:#"segue identifier to home VC" sender:self.window.rootViewController];
});
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
[self.window.rootViewController performSegueWithIdentifier:#"segue identifier to login VC" sender:self.window.rootViewController];
});
}
});
return YES;
}
And this is my quick storyboarding to assist the code. Hopefully you get the idea.