SecItemAdd always returns error -34018 in Xcode 8 in iOS 10 simulator

32,342

Solution 1

I was able to work around this in my app by adding Keychain Access Groups to the Entitlements file. I turned on the Keychain Sharing switch in the Capabilities section in your test app, and it is working for me as well.

Screenshot of turning on the switch

Item to add to entitlements:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)com.evgenii.KeychainBugDemo</string>
</array>

I have only tried this on macOS Sierra (10.12), so I'm not sure if it will work for you on 10.11.5.

Solution 2

In Xcode 8.1 GM Release Notes Apple acknowledged the problem and suggested a cleaner workaround:

Keychain APIs may fail to work in the Simulator if your entitlements file doesn’t contain a value for the application-identifier entitlement. (28338972) Workaround: Add a user-defined build setting to your target named ENTITLEMENTS_REQUIRED and set the value to YES. This will cause Xcode to automatically insert an application-identifier entitlement when building.

Note that from what I have tried, it only works in Xcode 8.1. Although the text can mislead you into a build setting, what you need to do is add this to your Environment Variables, in your scheme.

enter image description here

Xcode 8.2 will solve this:

Resolved in Xcode 8.2 beta - IDE Keychain APIs work correctly in Simulator. (28338972)

Solution 3

This can happen if you have a test target that does not have a host app. To fix

  1. add a dummy host app : enter image description here

  2. Enable automatic code signing and add a team :

enter image description here

  1. Enable keychain sharing in capabilities

enter image description here

Solution 4

I got an error while signing with email, creating a new user or with sign out using firebase.

The error was:

firauth error domain code 17995

I turned on the Keychain Sharing switch in the Capabilities section in your test app, and it is working for me as well.

Solution 5

I was looking for a solution that didn't use Keychain sharing, as that wasn't the feature I was looking for. The developer forum Seems to have a good work around from EvergreenCoder that you can limit in scope to only the iOS 10 simulator (as this seems to be the only affected simulator). From the post:

The issue seems to be that there must be at least one entitlement in order for Xcode to properly add the "application-identifier" enttilement to the built application. This is why keychain sharing seems to be a solution but it is only indirectly so: any other entitlement seems to work fine.

You can create a .plist like so:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-/  
<plist version="1.0">  
    <dict>  
        <key>get-task-allow</key>  
        <true/>  
    </dict>  
</plist>

and provide a path to that file under Build Settings in

Code Signing->Debug->Simulater iOS 10 SDK->($SRCROOT)/your-path-to-file

As stated in the post, this entitlement just allows the debugger to be attached.

Share:
32,342

Related videos on Youtube

Evgenii
Author by

Evgenii

I was born in Russia and have been working as a programmer since 1998. In 2012 my wife and I immigrated to Australia where I was working as a web and iOS developer. Currently I am doing a career change by studying astronomy in Monash University. I want to learn how the Universe works.

Updated on October 24, 2020

Comments

  • Evgenii
    Evgenii over 3 years

    Update: This issue has been fixed in Xcode 8.2. Keychain works in the simulator without enabling keychain sharing.

    Why am I always receiving error -34018 when calling SecItemAdd function in Xcode 8 / iOS 10 simulator?

    Steps to Reproduce

    Create a new Single page iOS app project in Xcode 8. Run the following code in viewDidLoad (or open this Xcode project).

    let itemKey = "My key"
    let itemValue = "My secretive bee 🐝"
    
    // Remove from Keychain
    // ----------------
    
    let queryDelete: [String: AnyObject] = [
      kSecClass as String: kSecClassGenericPassword,
      kSecAttrAccount as String: itemKey as AnyObject
    ]
    
    let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)
    
    if resultCodeDelete != noErr {
      print("Error deleting from Keychain: \(resultCodeDelete)")
    }
    
    
    // Add to keychain
    // ----------------
    
    guard let valueData = itemValue.data(using: String.Encoding.utf8) else {
      print("🐣🐣🐣🐣🐣🐣🐣🐣🐣🐣 Error saving text to Keychain")
      return
    }
    
    let queryAdd: [String: AnyObject] = [
      kSecClass as String: kSecClassGenericPassword,
      kSecAttrAccount as String: itemKey as AnyObject,
      kSecValueData as String: valueData as AnyObject,
      kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
    ]
    
    let resultCode = SecItemAdd(queryAdd as CFDictionary, nil)
    
    if resultCode != noErr {
      print("🐝🐝🐝🐝🐝🐝🐝🐝🐝 Error saving to Keychain: \(resultCode).")
    } else {
      print("🍀🍀🍀🍀🍀🍀🍀🍀🍀 Saved to keychain successfully.")
    }
    

    Expected Results

    Item is added to Keychain.

    Actual Results

    Function SecItemAdd returns the following error code: -34018.

    Version

    Xcode version 8.1 (8B62), macOS Sierra 10.12.1.

    Configuration

    Always occurs in Xcode 8 since Beta 2 when testing in an iOS 10 simulator.

    Does NOT occur in Xcode 8 when testing in an iOS 9.3 simulator.

    Demo

    https://dl.dropboxusercontent.com/u/11143285/2016/07/KeychainBugDemo.zip

    References

    Radar: https://openradar.appspot.com/27422249

    Apple Developer Forums: https://forums.developer.apple.com/message/179846

    This issue is different from the following post because it occurs consistently in Xcode 8. SecItemAdd and SecItemCopyMatching returns error code -34018 (errSecMissingEntitlement)

    • Nicholas Harlen
      Nicholas Harlen over 7 years
      This still appears to be an issue in Xcode 8 GM. Nice to see Apple is still on top of their game...
    • Nicolas Miari
      Nicolas Miari over 7 years
      I'm really digging your console logs :-)
    • Adil Hussain
      Adil Hussain over 6 years
      The issue was fixed in Xcode 8.2 but it's back in Xcode 9.0!
  • Stefan
    Stefan over 7 years
    Same here, only that I am using Xcode 8 beta 5 currently (with iOS 10 simulator. Problem didn't show up with previous beta. Also does not happen when testing with 8b5 on a real iOS 9 iPhone). I noticed that the Push Notifications in Capabilities needed fixing (i.e. pressing the button) and also turned Keychain Sharing on, unfortunately at the same time. Then the app did not get the error anymore. After turning off Keychain Sharing again, it still works!
  • Sam Jarman
    Sam Jarman over 7 years
    I use the keychain a test target and it fails - how would I get around this? (Since there are no capabilities in test targets)
  • Jordan
    Jordan over 7 years
    @SamJarman I had this problem too. I just went into the build settings for the test target & un-set the entitlements field. Worked fine after that.
  • Jan Nash
    Jan Nash over 7 years
    This solution works well for App Targets. Unfortunately, I'm working on a Swift framework that uses KeychainSwift which doesn't build anymore due to the error. In a framework target, I can't add an entitlements file afaik. Does anyone know a workaround for this case?
  • Evgenii
    Evgenii over 7 years
    @JanNash, here is how I managed to make the testing work evgenii.com/blog/testing-a-keychain-library-in-xcode
  • Maksim
    Maksim over 7 years
    @Evgenii thanks for your article! For some reason in my build target Host Application was not set up. After I selected my app's target there keychain started to work in iOS 10 simulator. And it seems not really necessary to have keychain-access-groups, for me it was just enough to have entitlements file with aps-environment set for development (this solves a warning during development runs of the app on device).
  • William Hu
    William Hu over 7 years
    @MaximMikheev What do you mean asp-environment set for development. I turned on the keychain share doesn't help : (
  • StrAbZ
    StrAbZ over 7 years
    Also if you have one target but different bundle IDs (for dev en release for example), you'll have to create entitlements for each one.
  • RvdB
    RvdB over 7 years
    The answer by Deyton works like a charm if you are in the position where you can enable Automatic Code Signing. If you need to leave Code Signing to manual, you should add the correct Code Signing Identity to "Any iOS SDK" in the Build Settings tab of your target. So: - Follow the steps in Deyton's answer - Add Code Signing Identity to "Any iOS SDK" below the build configurations (image)
  • guywithmazda
    guywithmazda over 7 years
    @Tiago Is this workaround from the release notes still working for you in Xcode 8.1 on the iOS 10.1 simulator? I've tried adding this setting (both as a User-Defined setting on the target, and as a an Environment Variable in the scheme), and I still get the -34018 return value when running on the iOS 10.1 simulators.
  • keithbhunter
    keithbhunter over 7 years
    @guywithmazda, same here. Still getting -34018 and tried both build settings and environment variables.
  • Evgenii
    Evgenii over 7 years
    Does not work for me, neither in build settings nor as a scheme's environmental variable in Xcode 8.1 (8B62) on Sierra. Am I missing something?
  • notthehoff
    notthehoff over 7 years
    Also getting this error. Adding as env variable not fixing.
  • weienw
    weienw over 7 years
    I had to manually add the entitlement, a la: key: application-identifier, <array><string>my.application.id</string></array>
  • DShah
    DShah over 7 years
    I am using Xcode 8.2.1 and this issue is still reproducible. Also, my question is if I dont have host app, and I am creating the Framework target, then how to resolve this issue?
  • russbishop
    russbishop over 7 years
    This problem still affects unit tests for Framework targets because in this case it would be the test host stub that needs entitlements. We are aware of the issue but if it is a blocker for you please file a duplicate bug.