Так что в моем приложении, когда пользователь успешно войдет в систему с именем пользователя и паролем, цепочка для ключей сохранит имя пользователя и пароль.Реализация цепочки для ключей взята из этой ссылки .
Вот моя реализация входа в систему, где цепочка для ключей сохраняет имя пользователя и пароль:
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
.Я сделал некоторую отладку, и я уверен, что это сохраняет его в связке ключей.Я даже создаю отдельный проект, чтобы доказать себе, что пример кода от Apple действительно работает.Может ли быть так, что я сохраняю пароль из фонового потока, и у меня есть доступ к цепочке для ключей в основном потоке в моем loginViewController
?
Спасибо!
Обновление
Вот код доступа к цепочке для ключей в loginViewController
:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
print(try! client.keychainItem?.readPassword())
}