仅当令牌不为零时如何执行 segue swift 5
How to perform segue ONLY if token not nil swift 5
正如标题所说,我正在处理登录问题。 tokenHandler 已经在工作并且我正在使用 KeychainAccess。
这是我的 tokenHandler class:
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:
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)
}
}
我还不是熟练的 swift程序员,所以如果你们中的任何人能给我一些好的建议,我将很高兴。我正在阅读并尝试使用 delegate 原则,但坦率地说,我的直觉告诉我,这不是我需要的。
我正在阅读
PerformSegueWithIdentifier
但不太了解如何将其转换为我的代码...
我在情节提要中包含的转场正在运行,但不幸的是,如果测试用户没有登录。所以,我按下登录按钮 w/o 任何用户名和用户密码,我无论如何都会进入下一个视图。不太酷,所以请帮助我:)
编辑: 我将 performSegue 更改为 shouldPerformSegue 但我仍然可以访问下一个查看 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."]}}
所以错误是正确的,但是按下 "Login" 按钮我仍然会进入下一个视图。
编辑:
我尝试了一些更改,现在我有例如:
if tokenHandler.getTokenFromKeyChain() != nil
而不是
let token = tokenHandler.getTokenFromKeyChain()
if token != nil
显然,我在此 IBAction 中为 LoginButton 所做的任何事情都没有任何不同。我错过了什么?
好吧,在我看来,如果自从您成为 运行 您的 device/simulator 上的应用程序以来,您曾经调用过 saveTokenToKeyChain()
,那么钥匙串将保存一些字符串,因为我看不到你在哪里将它设置为 nil(我根本看不到你在哪里设置它,但假设你删除了保存令牌的代码)。所以你当前的逻辑是,如果你有一些字符串保存为标记(无论它是空字符串、随机字符串还是过期的标记),它会执行 segue。无论在那里留下什么,getTokenFromKeyChain()
都会 return 你一个字符串,所以你的 if token != nil
将始终评估为 true
.
另一方面,如果你清除KeyChain数据,因为我找不到任何保存令牌的代码,UI总是会说登录失败,即使它实际上成功。
因此您应该使用 writing/deleting 令牌 to/from KeyChain 正确处理登录 success/failure。
正如标题所说,我正在处理登录问题。 tokenHandler 已经在工作并且我正在使用 KeychainAccess。 这是我的 tokenHandler class:
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:
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)
}
}
我还不是熟练的 swift程序员,所以如果你们中的任何人能给我一些好的建议,我将很高兴。我正在阅读并尝试使用 delegate 原则,但坦率地说,我的直觉告诉我,这不是我需要的。 我正在阅读
PerformSegueWithIdentifier
但不太了解如何将其转换为我的代码...
我在情节提要中包含的转场正在运行,但不幸的是,如果测试用户没有登录。所以,我按下登录按钮 w/o 任何用户名和用户密码,我无论如何都会进入下一个视图。不太酷,所以请帮助我:)
编辑: 我将 performSegue 更改为 shouldPerformSegue 但我仍然可以访问下一个查看 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."]}}
所以错误是正确的,但是按下 "Login" 按钮我仍然会进入下一个视图。
编辑: 我尝试了一些更改,现在我有例如:
if tokenHandler.getTokenFromKeyChain() != nil
而不是
let token = tokenHandler.getTokenFromKeyChain()
if token != nil
显然,我在此 IBAction 中为 LoginButton 所做的任何事情都没有任何不同。我错过了什么?
好吧,在我看来,如果自从您成为 运行 您的 device/simulator 上的应用程序以来,您曾经调用过 saveTokenToKeyChain()
,那么钥匙串将保存一些字符串,因为我看不到你在哪里将它设置为 nil(我根本看不到你在哪里设置它,但假设你删除了保存令牌的代码)。所以你当前的逻辑是,如果你有一些字符串保存为标记(无论它是空字符串、随机字符串还是过期的标记),它会执行 segue。无论在那里留下什么,getTokenFromKeyChain()
都会 return 你一个字符串,所以你的 if token != nil
将始终评估为 true
.
另一方面,如果你清除KeyChain数据,因为我找不到任何保存令牌的代码,UI总是会说登录失败,即使它实际上成功。
因此您应该使用 writing/deleting 令牌 to/from KeyChain 正确处理登录 success/failure。