0.6.0
License state now lives in a device-bound encrypted file by default, and the Keychain is left untouched — so the OS no longer shows a Keychain permission prompt on first launch. This is the new default; no code change is required to get it.
Added
StorageBackendconfiguration enum with two cases:.encryptedFile(keychainMirror: Bool = false)— new default. The license/trial blob is sealed with a key derived from the device identity, yourtenantId, andproductId, and stored under Application Support. The Keychain is never read or written, so there is no first-launch popup. PasskeychainMirror: trueto also keep a Keychain recovery copy..keychain— legacy behavior: the Keychain is authoritative, with the encrypted file as a crash-recovery fallback.
KeylightConfiguration.storage: StorageBackendinitializer parameter (defaults to.encryptedFile()).
Changed
- Default storage backend is now
.encryptedFile()instead of Keychain-authoritative. Existing on-disk license/trial state is migrated automatically and popup-free: on first load the SDK reads the legacy files, re-seals them into the encrypted file, and deletes the originals. Migrated installs keep their license — no re-activation.
Migration
- Most apps: nothing to do. The new default removes the first-launch Keychain prompt and migrates existing on-disk state automatically.
- If you relied on license state living in the Keychain specifically (e.g. you read it outside the SDK, or want Keychain sync/restore), set
storage: .encryptedFile(keychainMirror: true)to keep a Keychain copy, orstorage: .keychainto retain the previous default. - On platforms without Application Support (e.g. watchOS) or when a stable device ID is unavailable, the SDK transparently falls back to the Keychain — it never locks the user out.
Unchanged
- No wire-format or server changes. Lease signing/verification and the public
LicenseManager/ provider surface are the same.