Как выполнить переход только если токен не nil swift 5 - PullRequest
0 голосов
/ 17 февраля 2020

Как видно из названия, я работаю над логином. TokenHandler уже работает, и я использую 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"
    }

}

А вот мой LoginV C класс:

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

, но не совсем понял, как преобразовать его в мой код ...

Сегменты, которые я включил в раскадровку, работают, но, к сожалению, также, если тест пользователь не сделал логин. Итак, я нажимаю кнопку входа в систему без имени пользователя и userpwd, и я в любом случае получаю следующий вид. Не круто, поэтому помогите мне, пожалуйста:)

РЕДАКТИРОВАТЬ: Я изменил executeSegue на shouldPerformSegue , но я все еще получаю доступ к следующему View w / o любое разрешение.

РЕДАКТИРОВАТЬ: Я получаю:

-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 для LoginButton, не делает ничего другого. Чего мне не хватает?

1 Ответ

0 голосов
/ 17 февраля 2020

Что ж, мне кажется, что если вы когда-то звонили saveTokenToKeyChain() с тех пор, как вы запустили приложение на своем устройстве / симуляторе, то KeyChain будет держать там некоторую строку, так как я не вижу, где вы устанавливаете его на ноль (я вообще не вижу, где вы его установили, но давайте предположим, что вы удалили код, который сохраняет токен). Итак, что делает ваш текущий logi c, так это то, что он выполняет переход, если у вас есть какая-то строка, сохраненная как токен (неважно, пустая ли это строка, произвольная строка или токен с истекшим сроком действия). Что бы там ни было, getTokenFromKeyChain() вернет вам строку, поэтому ваш if token != nil всегда будет иметь значение true.

С другой стороны, если вы очистите данные KeyChain, так как я не могу найти Любой фрагмент кода, который сохраняет токен, пользовательский интерфейс всегда скажет, что вход в систему не удастся, даже если он действительно успешен.

Таким образом, вы должны обработать успех / неудачу входа в систему с правильной записью / удалением токена в / из брелка.

...