What is the equivalent of iOS applicationWillTerminate in IBM MobileFirst Hybrid app? - ios

Scenario:
I want to call the logout function if the app is terminated. I'm able to do it using native code:
- (void)applicationWillTerminate:(UIApplication *)app
{
// Run Logout function
}
Problem:
How to do it in IBM mobilefirst hybrid app?
// ************************************************
Edited
First of all, user login in to the app, if the user key in the correct user id and password, it will add the userIdentity into "loginRealm".
WL.Server.setActiveUser("loginRealm", userIdentity);
Next, user closes the apps without logout. So, when the user login for the another time, MFP server will not return any feedback since it will hit this exception:
Cannot change identity of an already logged in user in realm
'loginRealm'. The application must logout first.
Hence, I have to logout the user from MFP server by setting the "loginRealm" to null in adapter;
WL.Server.setActiveUser("loginRealm", null);
The above line of code is in the logout function defined in authentication-config.xml.
The client side device runs this line of code and it will trigger the logout function. Besides, it will reload the App upon success:
WL.Client.logout('loginRealm', {
onSuccess: WL.Client.reloadApp
});
Steps that I've tried:
1) At WlcommonInit() I added WL.Client.updateUserInfo(); and if WL.Client.isUserAuthenticated("loginRealm") return true I will logout the user from server. However, WL.Client.isUserAuthenticated("loginRealm") will always return false. This is because, it needs to take sometime around (30seconds to 2 minutes) for the flag to turn true after WL.Client.updateUserInfo();. So my login still fail and hit the same error.
2) I tried to logout the users during the user click login button. But the app will refresh and return to login page again due to reloadApp. The logout code I get from IBM mobilefirst website. So user need to click and type 2 times in order to login into the main menu.
WL.Client.logout('loginRealm', {
onSuccess: WL.Client.reloadApp
});
Am I doing it wrongly? Or are there any other methods to get WL.Client.isUserAuthenticated("loginRealm") return true instantly after WL.Client.updateUserInfo(); ? Can we remove the reload app line of code in logout function?

I don't think this is doable, because that logout function (in MFP) will require server connectivity (request and response) and if the app is by then killed, I think it's going to cause unpredictable results.
Note though that it seems to be not recommended to use that function anyway? applicationWillTerminate when is it called and when not
What you should do perhaps in order to simulate it, is to logout-on-login, so that it would appear that the app is logged out when opening it. You can extend the duration of the splash screen so that the end-user will not see that s/he is logged in (in case the session was still alive between the closing and re-opening of the app), until really logged out and then you can display the login screen again or any other required screen.

Related

App Tracking Transparency reset after user choice

I've just implemented the ATT request in my applications. It appears at the app first opening but I would like to show it again if the user wants to change his preferences from the app settings (internal).
I tried to call the requestTrackingAuthorization method again but it enters immediately to the completion handler. Is there a way to reset the status?

Automatically log out user when they leave the iOS app

I have an in-house app which is used by staff but the chances are the device it is used on could become consumer facing. With that in mind I want to ensure that should the staff forget to logout when they switch apps or just reopen the app that I have a command in there to effectively log them out.
After researching I think the best way for me would be to use:
optional func applicationWillEnterForeground(_ application: UIApplication)
and then force the app to go to the login page or the reverse so that when app enters background it forces the app to the logout URL.
Which do you think would be best and how can I use that command to then add in the chosen URL as described above?
So, while I agree with #Rakesha-Shastri in that ""app enters background it forces the app to the logout URL" This seems like bad UX. The first one where you display the login page on returning from background seems fine. It is important that the user is able to resume his work where he left off after logging in again," there does need to be a way, in-case a user is gone too long, that the credentials have passed. It seems in your case, that every time the user LEAVES or CLOSES the app, you want this to be unauthenticated. What if the user gets a phone call? Should it do that? You may want to use Timer, of say some period of time, 2-5 minutes maybe.
Any who, what you can do is force the user to have to RESTART the app, by either presenting a controller that has NO CAPABILITY of going anywhere, therefore forcing a restart, or providing a button that sends them to a login screen you have implemented.
Note:
I would definitely indicate to the user, "due to purposes of security, each time you exit the app, it requires an authentication to re-access. Please log back in". Then provide a button to the login screen.
As you did not provide code, and I'm not going to do this for you, a direction to take this would be to utilize optional func applicationWillEnterForeground(_ application: UIApplication) alongside with getting the current UIViewController. I would google how to do that. Then from there, you can create a new UIViewController that presents this button back to the login screen.

GameCenter - Login user if they already entered their credentials

In my game I don't want the GameCenter login popup appearing automatically when the app launches. So instead I have a GameCenter button that the user can tap to login with. When they press the button, the login screen appears.
However, it seems like when you launch the app again after logging in, the user still isn't "logged in". They still have to press the button again and then a little banner appears saying "Welcome back, User!". Is there a way to automatically relogin the user without them having to press the button each time? I already entered my credentials, why do I have to authenticate again?
Here is my code, when the user presses the button:
self.authenticatePlayer()
And here's the authenticate method:
func authenticatePlayer() {
let localPlayer = GKLocalPlayer.localPlayer()
localPlayer.authenticateHandler = {
(view, error) in
if view != nil {
self.view?.window?.rootViewController?.presentViewController(view!, animated: true, completion: nil)
} else {
}
}
}
I need something that can welcome back the user if they already logged in, but NOT ask them to login if they haven't logged in already.
To understand the behavior you're seeing, we need to look at how the authentication process works.
It starts when you set the authentication handler. This is the signal that tells your app to try and talk to Game Center. The authentication handler's completion block has three possible conditions:
Error: something went wrong
Receives a view controller: the login view controller tells you the player isn't logged in
Receives nil view controller: the lack of an error + lack of a view controller tells you the player was already logged in.
Although IOS may be aware of your login state (or attempting to fake your login state using cached info), your app loses that context when you exit. When you startup again, there's been no attempt to set the authentication handler, thus no attempt to verify authentication status until your user presses the button, thus your app doesn't know whether the user is logged in or not.
I think the following approach will get pretty close to what you're looking for:
set the authentication handler and initiate the authentication as early as possible in your first viewController's viewDidLoad. Do this as early as possible in your start up sequence.
If the user isn't authenticated, you will receive a login view controller. Don't present it. Instead, save it. Don't present it unless/until the user presses the button.
If the user is already logged in, they will see the welcome back message as soon as the game starts, and you'll be able to proceed since the user is still logged in.

What is the proper way to handle FBSessionStateClosedLoginFailed with iOS FB SDK 3.1.1

When my app needs to e.g. read from a user's facebook, it checks the current state the active FBSession. For the e.g. FBSessionStateOpen, it knows it can just request the information from Facebook, whereas for FBSessionStateCreatedTokenLoaded it must call openWithCompletionHandler. What FBSession method should be called if the current state is FBSessionStateClosedLoginFailed?
That means that a login attempt failed. When this happens for me I - closeAndClearTokenInformation and alert the user that login failed and ask him if he wants to login again.
In short:
In Facebook sample
https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/
When such condition occurred, their sample code will call a loginViewController or equivalent.
This is their comments when falling into this condition.
"if the token goes invalid we want to switch right back to the login view, however we do it with a slight delay in order to account for a race between this and the login view dissappearing a moment before "
P.S. I fixed this error my solving Facebook open graph setups and study more on the Scrumptious example such as "return [FBSession.activeSession handleOpenURL:url];" and "[FBSession.activeSession handleDidBecomeActive];"
In long:
This is taken from official FB doc.
http://developers.facebook.com/docs/reference/ios/3.1/class/FBSession#FBSessionState+enum
Given this is the precondition and it has passed other enum states and not a connection error:
"FBSessionStateClosedLoginFailed
Closed session state indicating that a login attempt failed"
It didn't explicitly said the problem. It may be the cached misinformation. Personally and most carefully, I would call '- (void)closeAndClearTokenInformation;", this method would clean up every cache info and show a error message such as "invalid login, please try again" to the client/user.
Then, allow the client the options to do a clean slate login again or skip this process if possible.
HTH

Facebook Connect - I always have to click logout before I can log in?

As the title says, my project will never bring up the FB login screen until I have called
[facebook logout];
This makes sense when I've already logged in, but it happens on startup as well (i.e. the user is not yet logged in).
Hmmm...I've just tried resetting contents and settings in the simulator, and that seems to have fixed the problem. For my own peace of mind, why when I close the simulator and rerun the project does it not revert to either a state where the app is 'new' and hasn't been run before, or to a resume state - whereby the logged in user info would be available immediately?
On my device I have just tested this:
Fresh install
Open app, login via FB Connect
Close app, remove from running in background apps
Reopen app
Try to login, no response until I first click logout
So is it somehow retaining the fact that it has logged in before? If so, is there a "loggedInAlready" variable or something similar that I can check against?
Added this to didFinishLaunchingWithOptions
if([facebook isSessionValid])//if already able to log in
{
[self loginToFacebook];//attempt to login automatically on startup
}
Seems to have solved the problem. I guess that because I had:
if([facebook isSessionValid]){
[facebook login];
}
in the login button press, that when it resumed it was still in a valid session and so the button press wouldn't do anything until the logout button ended the session.
Now it automatically checks if the session is valid on startup, and if so it logs straight in for me.
:-) All's well that ends well.

Resources