iOS KeyChain value not found at the beginning in first and second launches, then back to normal in third launches

Viewed 175

We have an app that needs to get the keychain values right after launch. I noticed that on the first and second launches after installation, the keychain values are not found until our check has finished. The keychain accessibility is set to .accessibleAfterFirstUnlock, and I have tried to observe ProtectedData Notification and applicationProtectedDataWillBecomeUnavailable delegate method, neither is called. The error received when not able to access keychain is errSecItemNotFound.

This stops happening since the third launch and things back to normal. The keychain values are accessible from beginning since the third launch. But the first and second launches are pretty important to our user experience, so we want to fix this. I wonder if anyone has seen similar things and how to resolve.

1 Answers

I propose to you this Framework: https://github.com/auth0/SimpleKeychain which you can embed with SPM And I use it in this way:

    import SimpleKeychain

    /// A helper function to load data from the Keychain
    func keyChainLoad(with key: String) -> String?
    {
        simpleKeychain.useAccessControl = false
        simpleKeychain.defaultAccessiblity = .whenUnlockedThisDeviceOnly
        
        return simpleKeychain.string(forKey: key)
        
    }
    
    func keyChainLoadData(with key: String) -> Data? {
        simpleKeychain.useAccessControl = false
        simpleKeychain.defaultAccessiblity = .whenUnlockedThisDeviceOnly
        return simpleKeychain.data(forKey: key)
    }
    
    /// A helper function to save data from the Keychain
    func keyChainSave(withValue value: String, forKey key: String)
    {
        simpleKeychain.useAccessControl = false
        simpleKeychain.defaultAccessiblity = .whenUnlockedThisDeviceOnly
        simpleKeychain.setString(value, forKey: key)
    }
    func keyChainSave(withData data: Data, forKey key: String)
    {
        simpleKeychain.useAccessControl = false
        simpleKeychain.defaultAccessiblity = .whenUnlockedThisDeviceOnly
        simpleKeychain.setData(data, forKey: key)
    }
    
    func keyChainDelete(forKey key: String)
    {
        simpleKeychain.useAccessControl = false
        simpleKeychain.defaultAccessiblity = .whenUnlockedThisDeviceOnly
        simpleKeychain.deleteEntry(forKey: key)
    }

prove it, it has never let me down

Related