KeychainAccess
KeychainAccess copied to clipboard
Migrating existing keychain to using accessGroup
Up until now, I've been initializing Keychain
with default options, like this: Keychain()
.
Recently, I added a new extension and enabled keychain sharing on both targets.
The initialization now looks like this: Keychain(service: "com.app", accessGroup: "PREFIX.SharedGroup")
.
The problem is that the new Keychain
using accessGroup
is empty, ie. does not include existing items that were stored using the old Keychain()
.
Is there a built-in way to migrate the old keychain items to the new one? Or do we have to do it manually?
We have faced a similar issue this month. We've been using Keychain
without accessGroup:
parameter so far and now that we have implemented NotificationService
we needed to share some of the items within those existing Keychains to the app group.
Since we did not find any built-in way to do it, we decided to manually migrate items from old keychain to the new shared one.
When creating a new keychain for sharing between apps within a group, we used the same service name as before, but this time we passed the accessGroup
parameter.
This caused some very interesting and at the same time confusing results. First attempt was to simply iterate between all keys in the old keychain and store them to the new one like so:
for key in oldKeychain.allKeys() {
newKeychain[key] = oldKeychain[key]
}
The newKeychain
looked fine after execution of this block, new values were added to it, great.
But the result was unexpected for the oldKeychain
, which now contained all old items AND all new items, so there were duplicate keys. 😮
For example, oldKeychain
contains item with key testKey
and after this block of code is executed, so does the newKeychain
. But now oldKeychain
contains 2 items with testKey
as key.
Now, before we knew this, we tried to clean up the old keychain with try oldKeychain.removeAll()
. This resulted in all items being removed, the old ones in oldKeychain
which is expected and the copied/migrated items in the newKeychain
which was completely unexpected.
So it appears that somehow the two keychains with the same name are tied together, even though one has accessGroup
and the other does not. I would assume this is the same keychain, but with different permissions of sorts.
But it does seem odd that the items migrated to newKeychain
do not override the old ones, but creates duplicates.
We solved this duplicate issue internally by clearing old keychain before storing new into the new shared keychain. To me the question still remains, is this intentional behaviour or possibly a bug? And if so, is there another way we could have resolved this migration process without creating duplicates or clearing old ones before adding new ones?
Still no fix on this issue?