所以在我的应用程序中,当用户使用用户名和密码成功登录时,钥匙串(keychain)将保存用户名和密码。钥匙串(keychain)的实现是从这个link .
这是我的登录实现,其中钥匙串(keychain)保存用户名和密码:
func loginUser(from url: URL, with username: String, and password: String, completionHandler: @escaping (DrivetimeUserProfile?, DrivetimeAPIError.LoginError?) -> Void) {
let request = makeLoginRequest(url: url, with: username, password: password)
let task = session.dataTask(with: request) { (data, response, error) in
guard let data = data else {
completionHandler(nil, .EmptyData)
return
}
do {
let userProfile = try JSONDecoder().decode(DrivetimeUserProfile.self, from: data)
completionHandler(userProfile, nil)
self.accountName = username
self.keychainItem = KeychainPasswordItem(service: KeychainConfiguration.serviceName, account: username, accessGroup: KeychainConfiguration.accessGroup)
try self.keychainItem?.savePassword(password)
} catch {
completionHandler(nil, .CannotDecodeJson)
}
}
task.resume()
}
}
然后,在我的 loginViewController
中,当点击 loginButton
时,它会调用 loginUser
,如下所示:
@IBAction func onLoginButtonTapped(_ sender: Any) {
let url = URL(string: BASE_URL)!
if !isUsernameAndPasswordIsFilled() {
let alert = makeAlertDialogue(with: "Incomplete Information", description: "Please make you enter both username and password")
present(alert, animated: true, completion: nil)
return
}
client.loginUser(from: url, with: userNameTextField.text!, and: passwordTextField.text!) { [weak self] (userProfile, error) in
self?.performUIUpdate {
guard error == nil else {
self?.handleLoginError(error: error)
return
}
self?.userProfile = userProfile
self?.performSegue(withIdentifier: "mainTabBarController", sender: nil)
}
}
}
但是,当我尝试访问保存的密码时,它检索到nil
。我做了一些调试,我确信它会将其保存在钥匙串(keychain)中。我什至创建了一个单独的项目来向自己证明来自苹果的示例代码确实有效。难道我是从后台线程保存密码,并且在我的 loginViewController
的主线程中访问钥匙串(keychain)吗?
谢谢!
更新
以下是在 loginViewController
中访问钥匙串(keychain)的代码:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
print(try! client.keychainItem?.readPassword())
}
最佳答案
我只是从您的链接安装示例项目,并且经过测试工作良好。 我假设您配置了 KeychainPasswordItem 类正确。 在您的代码中我看到一个用户名,您可以检查用户名与您的密码是否正确。
if let accountName = accountName {
do {
let passwordItem = KeychainPasswordItem(service:KeychainConfiguration.serviceName, account: accountName, accessGroup: KeychainConfiguration.accessGroup)
accountNameField.text = passwordItem.account
passwordField.text = try passwordItem.readPassword()
}
catch {
fatalError("Error reading password from keychain - \(error)")
}
}
关于ios - Swift Keychain 无法从 viewDidLoad 检索保存的密码以实现自动登录功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54918351/