Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何仅在令牌不为零的情况下执行segue swift 5_Swift_Xcode_Authentication_Keychain_Swift5 - Fatal编程技术网

如何仅在令牌不为零的情况下执行segue swift 5

如何仅在令牌不为零的情况下执行segue swift 5,swift,xcode,authentication,keychain,swift5,Swift,Xcode,Authentication,Keychain,Swift5,正如标题所说,我正在进行登录。tokenHandler已在工作,im使用KeychainAccess。 下面是我的tokenHandler类: import KeychainAccess class TokenHandler { func saveUsernameToKeyChain(username: String) { do { try keychain.set(username, key: "myUsername") }

正如标题所说,我正在进行登录。tokenHandler已在工作,im使用KeychainAccess。 下面是我的tokenHandler类:

import KeychainAccess

class TokenHandler {

    func saveUsernameToKeyChain(username: String) {
        do {
            try keychain.set(username, key: "myUsername")
        } catch let error {
            print(error)
        }
    }

    func getUsernameFromKeyChain() -> String? {
        return keychain[string: "myUsername" ]
    }

    func saveUserPasswordToKeyChain(password: String) {
        do {
            try keychain.set(password, key: "UserPassword")
        } catch let error   {
            print(error)
        }
    }

    func getUserPasswordFromKeyChain() -> String? {
        return keychain[string: "UserPassword"]
    }

    let keychain = Keychain(service: "com.mybackendpage")

    func getTokenFromKeyChain() -> String? {
        return keychain[string: "myToken"]
    }

    func saveTokenToKeyChain(token: String) {
        do {
            try keychain.set(token, key: "myToken")
        }
        catch let error {
            print(error)
        }
    }

    func saveRefreshTokenToKeyChain(refreshToken: String) {
        do {
            try keychain.set(refreshToken, key: "myRefreshToken")
        }
        catch let error {
            print(error)
        }
    }

    func loginToAPI(username: String, password: String) -> Any {
        guard let url = URL(string: "https:mypage.com") else
        {
            return ""
        }

        let jsonData = try? JSONSerialization.data(withJSONObject: [
            "email": username,
            "password": password
        ])

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        // insert json data to the request
        request.httpBody = jsonData

        URLSession.shared.dataTask(with: request) { (data, response, error) in
            guard error == nil else { print(error!.localizedDescription); return }
            guard let data = data else { print("Empty data"); return }

            if let str = String(data: data, encoding: .utf8) {
                print(str)
            }
        }.resume()

        return "TOKENSTRING"
    }

}
这是我的LoginVC课程:

class LoginViewController: UIViewController {

    let tokenHandler = TokenHandler()

    @IBOutlet weak var usernameTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let username = tokenHandler.getUsernameFromKeyChain()

        let userPassword = tokenHandler.getUserPasswordFromKeyChain()


    @IBAction func unwindToLogin(_ unwindSegue: UIStoryboardSegue) {
        print("-unwinding success-")

    }


    // func for the login button:
    @IBAction func loginButton(_ sender: UIButton) {
        activityIndicator.startAnimating()
        loginWithCredentials()

        let token = tokenHandler.getTokenFromKeyChain()

        if token != nil {
            performSegue(withIdentifier: "segueToNavigation", sender: self)
        } else if ( token == nil ){
            // create the alert:
            let alert = UIAlertController(title: "Wrong login data", message: "Please try again.", preferredStyle: UIAlertController.Style.alert)

            // add an action to the button:
            alert.addAction(UIAlertAction( title: "Ok", style: UIAlertAction.Style.default, handler: nil ))

            // show the alert:
            self.presentingViewController

            print("-Token could not be created.-")
        }

        else {
            // create the alert:
            let alert = UIAlertController(title: "Wrong login data", message: "Please try again.", preferredStyle: UIAlertController.Style.alert)

            // add an action to the button:
            alert.addAction(UIAlertAction( title: "Ok", style: UIAlertAction.Style.default, handler: nil ))

            // show the alert:
            self.presentingViewController

            print("-Token could not be created.-")
        }

    }

    func loginWithCredentials() {
        let username: String = usernameTextField.text!
        let password: String = passwordTextField.text!

        let authResponse = tokenHandler.loginToAPI(username: username, password: password)



    }

}
我还没有熟练的程序员,所以如果你们能给我一些好的建议,我会很高兴的。我在阅读并试图按照代表的原则工作,但坦率地说,我的直觉告诉我,这不是我所需要的。 我在读关于

PerformSegueWithIdentifier
但我真的不明白如何把它转换成我的代码

我在storyboardwise中包含的segues正在工作,但不幸的是,如果测试用户没有登录,它也会工作。所以,我按下了登录按钮,没有任何用户名和用户密码,我还是进入下一个视图。不酷,请帮帮我:)

编辑:我将performsgue更改为shouldPerformSegue,但我仍然可以在没有任何权限的情况下访问下一个视图

编辑:我得到:

-Token could not be created.-
{"message":"The given data was invalid.","errors":{"email":["The email field is required."],"password":["The password field is required."]}}
因此,错误是正确的,但按下“登录”按钮,我仍然可以进入下一个视图

编辑: 我尝试了一些改变,现在我已经为例如:

if tokenHandler.getTokenFromKeyChain() != nil
而不是

let token = tokenHandler.getTokenFromKeyChain()

        if token != nil

显然,我在这个IBAction中为登录按钮所做的一切都没有什么不同。我遗漏了什么?

好吧,在我看来,如果您在设备/模拟器上运行应用程序后调用过一次
saveTokenToKeyChain()
,那么钥匙链会在那里保留一些字符串,因为我看不到您在哪里将其设置为零(我看不出您在哪里设置它,但假设您删除了保存令牌的代码)。因此,您当前的逻辑是,如果您将某些字符串保存为令牌(无论是空字符串、随机字符串还是过期令牌),它将执行segue。剩下的是什么,
getTokenFromKeyChain()
将返回一个字符串,因此您的
if标记!=nil
将始终计算为
true

另一方面,如果您清除了KeyChain数据,因为我找不到任何保存令牌的代码,UI总是会说登录失败,即使它实际上成功了


因此,您应该通过正确地向KeyChain写入/删除令牌来处理登录成功/失败。

嘿,谢谢您的回复。基本上,我从这里实现了KeyChain内容:“”,并在方法中添加了特定于项目的内容。但是“if token!=nil将始终计算为true”听起来已经很合乎逻辑了。你知道我能做些什么来解决这个问题吗?我很确定,这个令牌是由“service:com.mybackendpage”提供的。