【问题标题】:Retrieving the account name from Keychain从 Keychain 中检索帐户名称
【发布时间】:2017-06-26 07:02:19
【问题描述】:

我想在钥匙串中保存和检索密码和用户帐户。我在 stackoverflow 中找到了一个解决方案,并在那里使用了代码。 Save and Load from KeyChain | Swift。但是这段代码只保存和加载密码而不是帐户名。我想我知道如何保存 accountName 但我需要弄清楚如何将它与密码一起加载。这是代码,可以节省您进入该链接的时间。

var userAccount = "AuthenticatedUser"
let accessGroup = "SecurityService"

// Mark: User defined keys for new entry
// Note: add new keys for new secure item and use them in load and save methods
let accountKey = "KeyForAccount"
let passwordKey = "KeyForPassword"

private class func save(service: String, data: String) {
        let dataFromString: NSData = data.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue), allowLossyConversion: false)! as NSData

        //Instantiate a new default keychain query
        let keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, dataFromString], forKeys: [kSecClassValue, kSecAttrServiceValue as NSCopying, kSecAttrAccountValue as NSCopying, kSecValueDataValue as NSCopying])

        //Add new keychain item
        let status = SecItemAdd(keychainQuery as CFDictionary, nil)
        if status != errSecSuccess {  //Always check status
            print("Write failed. Attempting update.")
            //updatePassword(token: data)
        }
    }
 private class func load(service: String) -> String? {
        //Instantiate a new default keychain query
        //Tell the query to return a result
        //Limit our results to one item
        let keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue as NSCopying, kSecAttrAccountValue as NSCopying, kSecReturnDataValue as NSCopying, kSecMatchLimitValue as NSCopying])

        var dataTypeRef: AnyObject?

        //Search for the keychain items
        let status : OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
        var contentsOfKeychain: String? = nil

        if status == errSecSuccess {
            if let retrieveData = dataTypeRef as? Data {
                contentsOfKeychain = String(data: retrieveData as Data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
            }
        } else {
            print("Nothing was retrieved from the keychain. Status code \(status)")
        }
            print(contentsOfKeychain ?? "none found")
            return contentsOfKeychain   
    }

完整的代码在链接内。谢谢大家。

【问题讨论】:

    标签: swift3 xcode8 ios10


    【解决方案1】:

    但此代码只保存和加载密码而不是帐户名。

    您显示的代码不会保存或加载密码或帐户名。

    你有两个功能,一个是保存键/值对,一个是加载键的值。调用这两个函数的方式决定了保存/加载的内容。

    您在代码中的某处调用save 来保存密码,您还需要调用save(使用不同的密钥)来保存帐户名。 load 也是如此。您的代码确实定义了要使用的两个键(accountKeypasswordKey)。

    HTH

    【讨论】:

    • ``` public class func savePassword(token: String) { self.save(service: passwordKey as String, data: token) } public class func loadPassword() -> String? { return self.load(service: passwordKey)``` 这两个函数调用它来保存和加载。如何修复 loadPassword 以使其包含该帐户?谢谢。
    • 您在评论中的问题的答案在我上面答案的最后一段。如果您在代码中编写了savePasswordloadPassword,和/或对它们的调用,那么我可能会误解您的问题,因为您既是 Swift 代码的作者,又按照我的理解提出了这个问题。对我来说没有意义..如果您没有编写代码,您可以不请为您编写代码的人向您详细解释吗?
    • 我是 swift 新手。基本上,我要求语法。我已经用我的能力尽力了。我很困惑,因为 load() 方法只返回一个字符串。我不认为它可以同时携带帐户和密码。我尝试返回一个数组,但从钥匙串中提取帐户名是另一个我不知道如何处理的问题。
    • "我不认为它可以同时携带账号和密码。" - 正如答案所说“您需要调用save(使用不同的密钥)来保存帐户名以及”。使用定义的函数调用save/load 处理单个键/值对,因此您调用这些函数两次,每个键一次 - 只需编写saveAccount/@ 987654332@。如果你希望你可以写saveAccountAndPassword/saveAccountAndPassword 来包装两个对save/load 的调用;在这种情况下,您可能希望加载函数返回一个 tuple;但目前这只是增加了复杂性。
    • 谢谢先生。我已经解决了。解决方案是我使用了一个不同的函数来返回一个字典。
    猜你喜欢
    • 2018-08-19
    • 2014-10-24
    • 2014-02-25
    • 2017-11-05
    • 1970-01-01
    • 2012-05-19
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多