2017-08-10 20 views
1

我正在使用XCode8 + Swift3開發iOS項目。成功將字符串值存儲到keychian中,但始終未能將其讀出

我創建了以下兩個函數來存儲串鑰匙圈&讀它從鑰匙扣回:

var query: [String: Any] = [ 
    kSecClass as String: kSecClassGenericPassword, 
    kSecAttrService as String: "my service", 
    kSecAttrAccount as String: "my-key" 
] 

func storeString(value: String) -> Bool { 
    if let data = value.data(using: .utf8) { 
     // delete data if exist 
     SecItemDelete(query as CFDictionary) 

     // add value to query 
     query[kSecValueData as String] = data 

     // add to keychain 
     let status = SecItemAdd(query as CFDictionary, nil) 

     return status == noErr 
    } 
    return false 
} 

func readString() -> String? { 
    // update query 
    query[kSecReturnData as String] = kCFBooleanTrue 
    query[kSecMatchLimit as String] = kSecMatchLimit 

    var result: AnyObject? 
    // fetch items from keychain 
    let status: OSStatus = withUnsafeMutablePointer(to: &result) { 
     SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) 
    } 

    // I always get error -50 here 
    if status == noErr { 
     if let resultData = result as? Data { 
      if let strVal = String(data: resultData, encoding: .utf8) { 
       return strVal 
      } 
     } 
    } 
    return nil 

} 

我調用功能:

boolean hasStored = storeString(value: "John") 
let readVal = readString() 

hasStoredtrue,但readVal總是nil。我調查了我的功能,我看到我總是在閱讀器功能中獲取錯誤-50作爲狀態代碼(請參閱我在我的函數中的註釋)。

爲什麼?爲什麼我不能看我存儲在鑰匙串中值(我不知道是否真的是存儲,但我得到status == noErr總是retuns truestoreString(value:)功能)

+0

如果將'kSecMatchLimit'的值設置爲'kSecMatchLimitOne',會發生什麼? – Max

+0

@Max,你可以請一個答案,我會接受它。它現在可以在改爲'kSecMatchLimitOne'之後運行。如果你還可以解釋一下爲什麼/你認爲'kSecMatchLimitOne'可以解決這個問題(爲了幫助其他人):) –

回答

2

。在你的代碼一個錯字:

query[kSecMatchLimit as String] = kSecMatchLimit 
//        ^~~~~~~~~~~~~~ 

kSecMatchLimit是關鍵而不是有效的值。預期值應爲CFNumberkSecMatchLimitOnekSecMatchLimitAll。如果您希望返回單個項目,請使用kSecMatchLimitOne。另見Search Attribute Keys and Values

相關問題