secItemAdd keep return -50 error in swift
I believe the value for the kSecValueData
key needs to be an NSData, not a String or NSString. Try encoding your string to data (with e.g. UTF-8 encoding). Untested snippet:
query[kSecValueData as String] = "b".dataUsingEncoding(NSUTF8StringEncoding)
For future reference, the error code -50 corresponds to errSecParam
, which the SecBase.h header documents as meaning: "One or more parameters passed to a function were not valid." If you see this error again, try changing the values that you're passing in with your query dictionary.
Slightly updated Swift 5 version of add to/remove from keychain functionality:
@discardableResult
func addToKeychain(_ value: Data, tag: Data) -> Bool {
let attributes: [String: Any] = [
String(kSecClass): kSecClassKey,
String(kSecAttrApplicationTag): tag,
String(kSecValueData): value
]
var result: CFTypeRef? = nil
let status = SecItemAdd(attributes as CFDictionary, &result)
if status == errSecSuccess {
print("Successfully added to keychain.")
} else {
if let error: String = SecCopyErrorMessageString(status, nil) as String? {
print(error)
}
return false
}
return true
}
@discardableResult
func removeFromKeychain(_ value: Data, tag: Data) -> Bool {
let attributes: [String: Any] = [
String(kSecClass): kSecClassKey,
String(kSecAttrApplicationTag): tag,
String(kSecValueData): value
]
let status = SecItemDelete(attributes as CFDictionary)
if status == errSecSuccess {
print("Successfully removed from keychain.")
} else {
if let error: String = SecCopyErrorMessageString(status, nil) as String? {
print(error)
}
return false
}
return true
}
Which can be used like this:
let value: Data = "key".data(using: .utf8)!
let tag: Data = "com.test.key".data(using: .utf8)!
removeFromKeychain(value, tag: tag)
addToKeychain(value, tag: tag)