Getting Optional(“”) when trying to get value from KeyChain

后端 未结 5 1433
自闭症患者
自闭症患者 2020-12-15 23:00

When I try to get my keyChain value, it return a string containing:

Optional(\"[thing in the KeyChain]\")

so, I tried to remove \"Optiona

相关标签:
5条回答
  • 2020-12-15 23:12

    Here is a Swift 2 example implementation:

    import Security
    
    class ZLKeychainService: NSObject {
    
        var service = "Service"
        var keychainQuery :[NSString: AnyObject]! = nil
    
        func save(name name: NSString, value: NSString) -> OSStatus? {
            let statusAdd :OSStatus?
    
            guard let dataFromString: NSData = value.dataUsingEncoding(NSUTF8StringEncoding) else {
                return nil
            }
    
            keychainQuery = [
                kSecClass       : kSecClassGenericPassword,
                kSecAttrService : service,
                kSecAttrAccount : name,
                kSecValueData   : dataFromString]
            if keychainQuery == nil {
                return nil
            }
    
            SecItemDelete(keychainQuery as CFDictionaryRef)
    
            statusAdd = SecItemAdd(keychainQuery! as CFDictionaryRef, nil)
    
            return statusAdd;
        }
    
        func load(name name: NSString) -> String? {
            var contentsOfKeychain :String?
    
            keychainQuery = [
                kSecClass       : kSecClassGenericPassword,
                kSecAttrService : service,
                kSecAttrAccount : name,
                kSecReturnData  : kCFBooleanTrue,
                kSecMatchLimit  : kSecMatchLimitOne]
            if keychainQuery == nil {
                return nil
            }
    
            var dataTypeRef: AnyObject?
            let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
    
            if (status == errSecSuccess) {
                let retrievedData: NSData? = dataTypeRef as? NSData
                if let result = NSString(data: retrievedData!, encoding: NSUTF8StringEncoding) {
                    contentsOfKeychain = result as String
                }
            }
            else {
                print("Nothing was retrieved from the keychain. Status code \(status)")
            }
    
            return contentsOfKeychain
        }
    }
    
    //Test:
    let userName = "TestUser"
    let userValue: NSString = "TestValue"
    print("userName: '\(userName)'")
    print("userValue: '\(userValue)'")
    
    let kcs = ZLKeychainService()
    
    kcs.save(name:userName, value: userValue)
    print("Keychain Query \(kcs.keychainQuery)")
    
    if let recoveredToken = kcs.load(name:userName) {
        print("Recovered Value: '\(recoveredToken)'")
    }
    

    Output:

    userName: 'TestUser'
    userValue: 'TestValue'
    Keychain Query [acct: TestUser, v_Data: <54657374 56616c75 65>, svce: Service, class: genp]
    Recovered Value: 'TestValue'

    0 讨论(0)
  • 2020-12-15 23:15

    You actually don't even need to do anything. The "Optional" string isn't in the actual data. That is just something Swift seems to place on the output on the console when it is an optional value that isn't unwrapped. IE The data itself doesn't contain the string Optional.

    Still, good to unwrap it if you know it contains data.

    0 讨论(0)
  • 2020-12-15 23:21

    You will get the Optional("") because the optional value is not unwrapped and if you want to unwrap the optional value to get the string value, do

    yourValue.unsafelyUnwrapped

    0 讨论(0)
  • 2020-12-15 23:29

    You can use the Swift wrapper over the Keychain C API, and avoid the above problems altogether. https://github.com/deniskr/KeychainSwiftAPI

    0 讨论(0)
  • 2020-12-15 23:36

    You get the Optional("") because the optional value is not unwrapped. You need to put a ! after the object and you won't get the Optional("") bit any more. I would show you the code but you haven't shown us the print() statement. I made some sample ones below that I think would replicate the problem, though I haven't tried them.

    var value:String?
    value = "Hello, World"
    
    print("The Value Is \(value)") // Prints "The Value Is Optional(Hello, World)"
    print("The Value Is \(value!)")// Prints "The Value Is Hello, World"
    

    Im hoping this answers your question or at least points you in the right direction, just ask if you need more information or a better example.

    0 讨论(0)
提交回复
热议问题