Getting data only when logged in - ios

In my app i have some functions: login, getNews, getWeather. The last two functions can be executed only if the user is logged in. I don't want to login everytime also if the user is already logged in, so if the two lasts functions returns a not logged in error i want to login and then executed the queue of functions that required the login.
That's only an example, the real code is much longer and the functions that depends on login are more than two. I want to know the best solution to manage that situation.

For example, you can store in UserDefaults state of logged in user or not. And base on this call any functions you want.

When the user has logged in you can store his credential in the keychain.
Look here for a brief tutorial:
Tutorial One
Tutorial Two.
Then you can check every time if you have his credentials stored and log in automatically, and then perform the functions getNews and getWeather.

To store data between your app launches, you can try any of the following two methods :
1) The very simple solution would be to store the user data in your UserDefaults in the form of user dictionary.
for ex. NSUserDefaults.standardUserDefaults().setObject(userDict, forKey: #"User Dictionary"). This can be painful if your userDict is large or difficult to make.
2) The other solution can be, use a archiver to store the user data. You can make your custom archiver from this link.

So when user success login use NSUserDefaults logged value = 1
Example;
Add prefs with that codes.
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
Success login after set logged object inside 1.
let logged = 1
prefs.setObject(logged, forKey: "logged")
And check user if logged or not logged show login
You can add under below check logged codes everywhere inside project
if prefs.valueForKey("logged") as! Int == 1 {
}else{
// go login
}
For logout you can use ;
let logged = 0
prefs.setObject(logged, forKey: "logged")
Thanks

Related

How to make app (with username/password login) know that a user is logged in?

I'm trying to make a login screen and made a database with Firebase by Google. The way I tried to make accounts in database is just by making a new child which is "Users" and then the next child would be a user (which is uniquely defined with a unique username). Then, user has other attributes and an attribute called loggedIn which is set to String 'false' but when on loginScreen login goes successfully set to String 'true'. How can I know after login and when that LoginViewController goes away which account has logged in exactly on that phone (simulator at the time) because there can be more users at one time with the attribute value 'loggedIn' set to 'true' and because of that can't go back to database to check that. I'm really new at this and don't know if this whole approach is okay by making in real-time database something like that and actually checking that by the attribute. Maybe I have to use some kind of a local database or something similar?
Swift 4, iOS development, Xcode 9
If you just want to persist locally the login status you may use UserDefaults. Just have a key called currentUser and set the value as his unique Id.
Once a user logs out just clear that key.
You can also use that to determine whether to launch the login screen when the app opens.
But it may be better to use something like AWS Cognito or similar services to handle user management.
Are you building an iOS app only or a cross-platform project?
I'm not sure this is the perfect answer for you. However, some of my apps use CloudKit and the login is authenticated and only then opens up areas of the app on the user's device. I'm sure if you wanted to check the status of successful logins, the authentication on the cloud could update as confirmation and you could subsequently access the cloud database using the CloudKit Dashboard.
It's quite intuitive and works seamlessly with Xcode.
I have a class called LoginManager, defined as an NSObject. Included in there is an optional String variable called accessToken with setter and getter functions for saving and retrieving my access token, including an option for clearing the token which would be used upon logout. There is also a function to check the status of the key.
var accessToken: String? {
get {
return //key from storage
}
set {
if newValue == nil {
//remove key from storage
} else {
//save key to storage
}
}
}
func isUserLogedIn() -> Bool {
return self.accessToken != nil
}
In my own case, I have an application manager object that changes the root view controller based on this info.
LoginManager.singleton.isUserLogedIn() ? loadMainView() : loadLoginView()
So the resulting view controller is never loaded unless the user is logged in. Is that useful to you?

iOS Swift Firebase - How to make Current user data available throughout the app?

I'm building an app using Firebase Database, Auth & Storage.
Basically, my users can sign up / sign in via Firebase Auth, then I store data for each of these users on Firebase Database.
I have been looking for the best way to get the Current User's data available throughout the app without having to re-fetch the information I need from Firebase on different screens.
Very few resources on Stack. Some people do talk about creating a CurrentUser singleton available globally, but others say that it's bad practice.
Now, maybe fetching the data as and when I need them might be the best practice solution, but I just felt it was strange to re-write the same piece of code again and again on each screens.
Any thoughts on this? I'd be really grateful if you guys have insights.
Isn't the logged in user data already available globally? I mean you can always access any logged in user related data by -
let userID = FIRAuth.auth()!.currentUser!.uid
The way uid available in this code snipped you can access any data related to user as long as the user is logged in. Do check if the current user is not nil before executing that, but i assume you will anyways take care of that.
You can make a struct with which you can access the values:-
struct userGlobalInfo{
var userID : String!
var userName : String!
var userEmail : String!
init(id : String!, name : String!, email : String!){
self.userID = id
self.userName = name
self.userEmail = email
}
}

How would I anonymous push username information to Parse

I've tried a few things, but nothing seems to work properly. I'm utilizing anonymous users and I have the User class in parse working fine, as it creates an autogenerated username for the current device utilizing the app.
I'd just like to attach the currentuser to my "createdBy" column alongside all the data in parse and I'm quite stumped as most things I've tried have failed.
Could you try this in viewDidLoad?
if let user = PFUser.currentUser() {
user["createdBy"] = user.username
user.saveInBackground()
}
It will push username to parse.com

Anonymously login auto generated user

I see that objectId of users generated locally and users created after anonymous login are not the same.
For example
PFUser.enableAutomaticUser()
let localUser = PFUser.currentUser()!.objectId!
print(localUserId) // "obj1"
PFAnonymousUtils.logInWithBlock {
(user: PFUser?, error: NSError?) -> Void in
let annonUserId: String = PFUser.currentUser()!.objectId!
print(annonUserId) // obj2
}
I want that obj1 to persist throughout the anonymous login phase.
Can I somehow "attach" the locally created user and login him anonymously? or is auto generated users are only useful for when you later upgrade him to a user&pass / social based logins ?
PFAnonymousUtils.logInWithBlock is defined to destroy existing anonymous user data and create a new clean anonymous user. You should only do that when the user is logged out.
If you enable anonymous users then one will be created initially and you can add whatever details you want to that. Then, later, when the user wants a real account use signUp: on the PFUser to convert it.
Note that anonymous users aren't real, you can't use them for everything. So, you may have some issues with them actually participating with other users. If this is the case then you may need to create real placeholder users with auto-generated login details and convert that at a later date by updating the username and sending a forgotten password e-mail (or similar).

How can I implement a "first time user registration" workflow in my Cocoa Touch app?

I'm implementing a "new user registration" in my app
The first time the user logs in, I'd like to have them complete a 4-step registration process to create their username, set their profile photo, etc.. Each step would be a different screen.
All this needs to be done just once. I was wondering -
What is the best setup for these 4 screens? Should they be a UINavigationController so that they are implemented as a "stack"? i.e. the user can go back to the previous screens?
How do I preserve the state of the registration? I'd like to know what step the user was on in case they leave halfway, or in general know whether I should display the registration (i.e. if this is their first time). Is there a way I can store the number of steps completed, so that if numStepsCompleted == 0 then I know they haven't started and if numStepsCompleted < 4 I know they have started but not finished?
In general, if there are any code examples online that implement something like this, it would be great to look at.
Thanks!
I would present a UINavigationController modally from you root view controller. One the user has finished you can do 2 things:
Save in NSUserDefaults the fact that the user has already complete the registration process. If the user delete the app, this flag will be removed with it.
Save personal information such username and password in the keychain, they will persist event after the remove of the application, that can be useful for silent login process and they are ciphered.
For the first point to can do something like that
+ (BOOL)isFirstTime{
static BOOL flag = NO;
static BOOL result;
if(!flag){
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"hasBeenLaunchedOnce"])
{
result = NO;
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"hasBeenLaunchedOnce"];
[[NSUserDefaults standardUserDefaults] synchronize];
result = YES;
}
flag = YES;
}
return result;
}
If this is the very first launch, show registration/login process, if not go along by taking username and password from keychain.
Save a value in NSUserDefaults to know which is the last completed step done by the user. As tou said, make a UINavigation to setup the four registration steps. When the app opens read the user defaults to know if the registration is finished.
There are a couple of different ways to implements this:
1. Use a UINavigationController
2. Use a UIPageViewController (which I like better)
3. Use a UITableView to contain all the information in one screen
To keep track of the registration info you should implement a RegistraionInfo class (or struct in Swift). Since there should only be one instance of it, you can create a singleton and access it from anywhere - RegistrationInfo.sharedInstance()
You can also create an instance in the first ViewController and pass it to the next one on prepareForSegue:.
The last part is to identify if the user already completed the Sign Up process. If you're using a Username/Password model then you should keep that info in the keychain and fetch it on launch.
Otherwise you can keep a value in NSUserDefaults.

Resources