Robert
Robert

Reputation: 1200

Error when saving to keychain using SecItemAdd

I'm getting an error saving an encoded value to keychain at the point of SecItemAdd. I'm fairly new to working with Keychain and not sure how to return the error to see what I'm doing incorrectly.

let encoder = JSONEncoder()


  func initiateLogin(forceReconnect: Bool = false, completion: @escaping (Bool)->Void) {
      Task {
          await loginUser(forceReconnect: forceReconnect, completion: { user in

              if let encoded = try? self.encoder.encode(user) {

                  // MARK: - keychain

                  let attributes: [String: Any] = [
                    kSecClass as String: kSecClassGenericPassword,
                    kSecAttrAccount as String: "johnDoe",
                    kSecValueData as String: encoded,
                  ]

                  if SecItemAdd(attributes as CFDictionary, nil) == noErr {
                      print("\(#function) 😀 user saved successfully in keychain")
                  } else {
                      print("\(#function) ⚠️ something went wrong")
                  }

                  self.initClient(withCredentials: user)
                  completion(true)
              }
        })
      }
    }

Upvotes: 0

Views: 1152

Answers (1)

timbre timbre
timbre timbre

Reputation: 13995

You didn't specify which error you are getting (it should be a return value of SecItemAdd), but the most common mistake is this: as documentation states:

The operation might fail, for example, if an item with the given attributes already exists.

In other words: your code will only work once for each unique kSecAttrAccount.

Instead, you need to check if an item already exists, and if yes, update it (or delete the previous one and create a new one).

How to update the items or delete them is explained here.

Side note: it's also a good idea to put keychain management into a separate class (a wrapper), which you can call from anywhere in your code to save / load data from keychain. Here's a good tutorial on how to create such wrapper.

Upvotes: 4

Related Questions