Xcode iOS: check if user is logged in and show dif

2020-03-05 02:24发布

I'm coding an app where a logged in user has got a couple of extra functionalities than a non logged in user. Basically, I have more or less 5 tabs. When I launch the app, the user immediately gets the login page. He can decide to skip it. If he skips it, there'll only be 3 tabs for him. If he logs in successfully, there'll be 5.

I already have my login page made. I just don't know how I can store a session if the user is logged in correctly, and only display a certain number of tabs if the user isn't. I come from PHP, I've just started learning Objective-C, so I'm looking for the same thing as $_SESSION in PHP, more or less.

So: if user logs in, store session, and show all the tabs. If he doesn't, only show a limited number of tabs. How should I approach this?

3条回答
▲ chillily
2楼-- · 2020-03-05 02:49

In terms of storing the session, I assume username and password is enough.

You could store the username as you wish in NSUserDefaults or CoreData if you are using it. Storing a password is best using the keychain. SSKeychain makes it easy to do this.

[SSKeychain setPassword:password forService:myAppName account:userName]

You could store the fact they are logged in in-memory, but on app relaunch check by:

NSString *password = [SSKeychain passwordForService:myAppName account:userName];
if (password != nil)
{
    // Logged in
}

If the user logs out, easy as deleting the password from the keychain by

[SSKeychain deletePasswordForService:myAppName account:userName]
查看更多
Anthone
3楼-- · 2020-03-05 02:51

Session handling is done automatically when you use NSURLConnection, so you can store the users data in a Sesssion on the server.

What you might be looking for is called a Singleton design pattern (some people reject it, but it can be very handy). What you do is create one object that is available everywhere in your code. In this object you for example store a BOOL that indicates whether the user has logged in or not. For example: (I didn't run this, just to get the idea)

Mananger myManager* = [Manager sharedManager];
if(myManager.loggedIn){
    //Show 5 tabs
}else{
    //Show 3 Tabs
}

This code can be used in every class so you can always access your user's data. Manager would be a seperate class in this case that provides singleton functionality. Check out how to make one here: http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/

查看更多
Lonely孤独者°
4楼-- · 2020-03-05 03:10

I'm gonna give you a comprehensive answer.

Don't use NSUserDefaults as session it's a bad solution

NSUserDefaults data is not encrypted, it may cause security issue.

Let's create a structured user class instead

When the user logged in, you will need to make sure you have access to user data throughout the app so you can get the data on any screen when you need it.

To achieve this, we need to make a great structure to organize this properly. Remember that current user and another users are both "user" so we will use the same class.

Create a class and name it "EDUser" (you can choose other name if you want).
This class will contain a user information (either current user or other user).
More than that, this class will have capability to log the user in.

Here's a picture of what the class might look like:

class EDUser {
    var firstName: String
    var lastName: String?
    var birthDate: NSDate?

    init(firstName: String, lastName: String?, birthDate: NSDate?) {
        self.firstName = firstName
        self.lastName = lastName
        self.birthDate = birthDate
    }
}

// MARK: - Accessor

extension EDUser {
    class var currentUser: EDUser? {
        get {
            return loadCurrentUserFromDisk()
        }
        set {
            saveCurrentUserToDiskWithUser(newValue)
        }
    }
}

// MARK: - Log in and out

extension EDUser {
    class func loginWithUsername(username: String,
                           andPassword password: String,
                           callback: (EDUser?, NSError) -> Void) {
        // Access the web API
        var parameters = [
            "username": username,
            "password": password
        ]
        YourNetworkingLibrary.request(.POST,
                          "https://api.yourwebsite.com/login",
                          parameters: parameters).responseJSON { 
            response in

            if response.statusCode == .Success {
                let user = EDUser(firstName: response["firstName"],
                       lastName: response["lastName"],
                       birthDate: NSDate.dateFromString(response["birthDate"]))
                currentUser = user
                callback(currentUser, nil)
            } else {
                callback(nil, yourError)
            }
        }
    }

    class func logout() {
        deleteCurrentUserFromDisk()
    }
}

// MARK: - Data

extension EDUser {
    class private func saveCurrentUserToDiskWithUser(user: EDUser) {
        // In this process, you encode the user to file and store it
    }

    class private func loadCurrentUserFromDisk() -> EDUser? {
        // In this process, you get the file and decode that to EDUser object
        // This function will return nil if the file is not exist
    }

    class private func deleteCurrentUserFromDisk() {
        // This will delete the current user file from disk
    }
}

// MARK: - Helper

extension NSDate {
    class func dateFromString(string: String) -> NSDate {
        // convert string into NSDate
    }
}

Use Case

Now with everything in place, we can use it like this

Non-blocking logging in process

EDUser.loginWithUsername(username: "edward@domain.com",
                         password: "1234") {
    user, error in

    if error == nil {
        // Login succeeded
    } else {
        // Login failed
    }
}

Logging out

EDUser.logout()

Check whether the user is logged in

if EDUser.currentUser != nil {
    // The user is logged in
} else {
    // No user logged in
    // Show the login screen here
}

Get current user data on any screen

if let currentUser = EDUser.currentUser {
    // do something with current user data
}

Store other user as object

let user = EDUser(firstName: "Edward",
                  lastName: "Anthony",
                  birthDate: NSDate())
查看更多
登录 后发表回答