Search code examples
ioswatchkitkeychainwatchos-2

Keychain access on watchOS 2 not working on the actual watch


I have read in the Apple developer forum that unlike watchOS 1, watchOS 2 does not share its keychain with the phone app so bam!! keychain sharing is not enabled by default we got to do a workaround for that.

Ok coming to my issue, I was trying to run a very basic keychain access program on the actual watch device running the latest beta (beta4) using a git library https://github.com/jrendel/SwiftKeychainWrapper

  let saveSuccessful: Bool = KeychainWrapper.setString("keychainData", forKey: "ImportantKeychainData")

  if saveSuccessful{
       let retrievedString: String? = KeychainWrapper.stringForKey("ImportantKeychainData")
       print(retrievedString)
     }
     else
     {
       print("unable to write keychain data")
     }

On the simulator it works like a charm but when I try to run the same on the actual watch it gives me an status code of -34018

There was no public documentation about this error code but I did a little digging to find out it turned out to be

errSecMissingEntitlement     = -34018,  /* Internal error when a required entitlement isn't present. */

source: http://opensource.apple.com/source/Security/Security-55471/sec/Security/SecBasePriv.h

I did a lot of research actually a full day on this and people pointed me to various directions, like memory issues, entitlements, profile issue, bug in keychain etc.

The catch here is that most of the dev's who reported this issue did not have it continuously like I got it on every run of the app, they had it at certain places only like when app was in background etc. To summarise,

1. I tried the same piece of code on iOS 9 beta 4 and it worked well on the phone.

2. The same code works well on the watch simulator.

3. The same code does not work on watchOS beta 4 returns -34018 continuously on the device but works well on the simulator.

4. All this testing is done using free provisioning introduced from Xcode 7, entitlements were added to the phone app and the watch extension, keychain sharing was enabled, app groups was enabled.

My questions are

1. Am I missing something here that I have to do with the device keychain that I am supposedly doing it wrong?

2. Is there an issue with free provisioning?

3. Is there an issue with the keychain perhaps??

Any help is appreciated.

FYI I also tried Apple's KeychainItemWrapper, customs code directly talking to SecItem methods nothing turned out to be fruitful.

Update, I tried this as well it fails as usual

let storableString:NSString = "keychain in watchos is working with simple code"  
  let query : [NSString : AnyObject] = [  
            kSecClass : kSecClassGenericPassword,  
            kSecAttrService : "WatchService",  
            kSecAttrLabel : "KeychainData",  
            kSecAttrAccount : "SecureData",  
            kSecValueData : storableString.dataUsingEncoding(NSUTF8StringEncoding)!  
        ]  
  let result = SecItemAdd(query, nil)  
  print(result)  

Update 2: Issue has been fixed in watchOS2 beta 5.


Solution

  • Issue has been fixed by Apple in the recent watchOS 2 beta 5.