0

我有一个使用 UserDefaults 存储用户数据(邮件和密码)的应用程序。一旦用户发送此信息,下次他/她打开应用程序时,应用程序不应显示注册视图(只要记录了用户数据)。

我认为这可以通过 Session 来完成,但我如何告诉应用程序只显示一次注册视图(或者当需要更改信息时)?这方面的一个例子可能是 Facebook 应用程序:您必须登录,当您再次打开应用程序时,所有内容都已加载(主屏幕)。

我的应用程序通过 PHP 将信息发送到域,因此 PHP 会话可能会有所帮助。

4

2 回答 2

0

您可以在应用程序中执行逻辑didFinishLaunchingWithOptions

func application(_ application: UIApplication, didFinishLauchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    guard let email = UserDefaults.standard.value(forKey: "email"), let password = UserDefaults.standard.value(forKey: "password") else {
        // Not set up yet
        showRegistration()
        return true
    }

    // Already signing up
    showLoginView()

    return true

}
于 2017-05-24T01:37:20.813 回答
0

有几种类型的身份验证,特别是当您处理移动应用程序和 API 时,您正在处理令牌。它通常是这样进行的:

  1. 您使用 API 开发人员或所有者为您的应用创建的clientSecret 和 clientId发送您的用户名和密码,以将其连接到服务器。示例代码:

    func loginUser(email:String, pass:String, completion:@escaping (_ status:Bool, _ error:Error?, _ msg:String?) ->())
    {
    
    //Get Api keys from plist file then send login request
    helper.getApiKeys { (id, key) in
    
        let parameters = [
    
            "grant_type":"password",
            "client_id":id,
            "client_secret":key,
            "username":email,
            "password":pass,
            "scope":""
    
            ] as [String : Any]
    
        let header = [
            "Content-Type":"application/json"
        ]
    
        Alamofire.request(loginUserURL!, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: header)
            .validate(statusCode: 200..<300)
            .responseJSON { (response) in
                switch response.result {
                case .success( _):
                    let json = response.result.value!
                    let swiftyJson = JSON(json)
                    guard let expires = swiftyJson["expires_in"].double else {
                        return
                    }
                    let accessToken = swiftyJson["access_token"].stringValue
                    let refreshToken = swiftyJson["refresh_token"].stringValue
                    self.helper.setToken(expires: expires, aToken: accessToken, rToken: refreshToken)
    
                    completion(true, nil, nil)
    
                case .failure(let err):
                    //print(err)
                    if response.response?.statusCode == 401 {
                        completion(false,err,"Invalid Username or Password")
                    } else {
                        completion(false, err, "Error Logging In")
                    }
                }
        }
    
    }
    
    }
    
  2. 您在闭包函数中收到我构建了一个“访问令牌”“刷新令牌”和一个“到期时间”

  3. 您在应用程序中保存令牌和到期时间UserDefaults,并将用户转到登录页面。示例代码:

    //Save token in userdefaults
    func setToken(expires:Double, aToken:String, rToken:String) {
    
    //Change to expiry unix timeinterval date
    let expiryTime = Date().timeIntervalSince1970 + expires
    
    let userDefaults = UserDefaults.standard
    userDefaults.set(expiryTime, forKey: "expires_in")
    userDefaults.set(aToken, forKey: "access_token")
    userDefaults.set(rToken, forKey: "refresh_token")
    }
    
  4. 然后在每次应用程序进入前台时,您都会检查用户是否已通过身份验证。这意味着您将检查是否有令牌保存在令牌UserDefaults的到期时间根据今天的时间戳仍然有效,如果它是由于到期您可以刷新您的令牌。示例代码:

    //Get tokens
    private func getTokens (completion:(_ expires:TimeInterval?, _ accessToken:String?, _ refreshToken: String?) ->())
    {
    let userDefaults = UserDefaults.standard
    let access = userDefaults.string(forKey: "access_token")
    let refresh = userDefaults.string(forKey: "refresh_token")
    let expiry = userDefaults.double(forKey: "expires_in")
    
    if (access != nil && refresh != nil) {
        completion(expiry, access, refresh)
    } else {
        completion(nil,nil,nil)
    }
    }
    
    //Check if user is already Authenticated
    func isAuth() -> Bool {
    
    var status = false
    var apiId = Int()
    var apiKey = String()
    
    //Get tokens and test expiry time
    getTokens { (expiry, accessToken, refreshToken) in
        if (accessToken != nil && refreshToken != nil) {
    
            //If due to expiry then refresh
            if ((expiry! - Date().timeIntervalSince1970) < 2592000 /* 1 month */ ) {
                print(expiry!); print(Date().timeIntervalSince1970)
                getApiKeys(completion: { (id, key) in
                    apiId = id
                    apiKey = key
                })
                refresh(refreshToken: refreshToken!, grantType: "refresh_token", clientId: apiId, clientSecret: apiKey, scope: "", completion: { (stat, err, msg) in
    
                    if stat {
                        status = true
                    } else {
                        status = false
                    }
                })
    
            } else {
                status = true
            }
    
        } else {
            status = false
        }
    }
    
    if status {
        return true
    } else {
        return false
    }
    }
    
  5. 所以这意味着用户始终处于登录状态,并且永远不会被发送到登录视图控制器,除非isAuth()函数返回 false。在我的情况下,过期日期或用户刚刚注销,我删除了他的令牌。示例代码:

    //Delete token for loggin out
    func logOut() {
    
    let userDefaults = UserDefaults.standard
    userDefaults.removeObject(forKey: "expires_in")
    userDefaults.removeObject(forKey: "access_token")
    
     // Segue user to login page
    
    }
    
于 2017-05-24T01:53:01.833 回答