简体   繁体   English

在Xcode中创建登录/注册视图

[英]Creating login/signup views in Xcode

I am making an app for iOS in Xcode. 我正在用Xcode为iOS开发一个应用程序。

My question is: How do I make the app show the signup/login view when it is needed, but not show it when the user is already logged in? 我的问题是:如何使应用在需要时显示注册/登录视图,而在用户已经登录时不显示? Is it communicating with the database every time the app launches? 每次启动应用程序时,它是否与数据库进行通信? I am planning on using MySQL for creating a database with simple users (username, score, friends). 我计划使用MySQL创建具有简单用户(用户名,得分,朋友)的数据库。 Is there a tutorial that will show me the steps for doing this? 有没有教程可以向我展示执行此操作的步骤? I have no experience with databases. 我没有数据库经验。

Help is appreciated. 感谢帮助。

You need to look at a bunch of tutorials, I recommend these guys: 您需要看一堆教程,我推荐这些人:

https://www.raywenderlich.com https://www.raywenderlich.com

They have free tutorials in ObjC and Swift as well as video courses! 他们有ObjC和Swift的免费教程以及视频课程!

A REST API normally respond with a 401 (Unauthorized code) if there isn't a valid/logged user, so every time I get a 401 I show a login within a modal view. 如果没有有效/登录的用户,REST API通常会以401 (Unauthorized code)作为响应,因此,每次获得401时,我都会在模式视图中显示登录信息。

So when you load the app, call a GET currentUser endpoint, if it returns a 401 the app will show the login, if not, the app will show the default rootViewController . 因此,当您加载应用程序时,请调用GET currentUser端点,如果它返回401 ,则该应用程序将显示登录名,否则,该应用程序将显示默认的rootViewController

I like this way because if for any reason, your session is no longer valid, the app will show the login view. 我喜欢这种方式,因为如果出于任何原因您的session不再有效,该应用将显示登录视图。

I'm gonna give you a comprehensive answer. 我要给你一个全面的答案。

Don't use NSUserDefaults and don't store password it's a bad solution 不要使用NSUserDefaults并且不要存储密码,这是一个不好的解决方案

NSUserDefaults data is not encrypted, it may cause security issue. NSUserDefaults数据未加密,可能会导致安全问题。

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). 创建一个类并将其命名为“ EDUser”(如果需要,可以选择其他名称)。
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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM