ios - Swift Keychain 无法从 viewDidLoad 检索保存的密码以实现自动登录功能

标签 ios swift keychain

所以在我的应用程序中,当用户使用用户名和密码成功登录时,钥匙串(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/

相关文章:

ios - 颜色色调 UIButton 图像

ios - 我应该只对多行页面使用 TableView 吗?

iOS 从云存储中选择图像

ios - 从音频文件中提取电平表

swift - 添加到 TableView 时 Realm 项会出现两次

ios - 一台 Mac 上的两个 iOS 开发人员许可证

ios - fatal error : unexpectedly found nil while unwrapping an Optional value (EXC_BAD_INSTRUCTION)

ios - CollectionViewCell 未创建

iOS 8 测试版 OSStatus -34018 (errSecMissingEntitlement)

iphone - 在应用程序安装过程中将加密 key 存储在钥匙串(keychain)中