I'm trying to sync authentication data from my iOS app to a Safari Web Extension using App Groups, but the extension isn't consistently receiving the data.
Setup:
- App Group:
group.com.airaai.AiraApp(configured in both app and extension) - iOS app writes auth data using
UserDefaults(suiteName: "group.com.airaai.AiraApp") - Extension's Swift
SafariWebExtensionHandlerreads from App Groups inbeginRequest() - Extension's JavaScript reads from
browser.storage.local
Problem: Extension popup always shows "logged out" even when:
- User is logged into main iOS app
- Auth data exists in App Groups (verified via native module logs)
- Handler successfully writes test values to extension storage
Current Behavior:
- Handler CAN read from App Groups ✅
- Handler CAN write test values to extension storage ✅
- But auth data doesn't appear in
browser.storage.localwhen popup checks ❌ - Popup reads empty keys even though handler logged writing them
Code:
// Handler reads from App Groups
guard let sharedDefaults = UserDefaults(suiteName: "groupName") else { return }
let authData = sharedDefaults.string(forKey: "auth_data")
// Handler writes to extension storage (tried multiple suite names)
let extensionDefaults = UserDefaults(suiteName: Bundle.main.bundleIdentifier ?? "")
extensionDefaults?.set(authData, forKey: "oauth_token")
extensionDefaults?.synchronize()
// Popup reads from storage
browser.storage.local.get(['oauth_token']).then(data => {
console.log(data); // Always empty {}
});
What I've tried:
- ✅ App Groups properly configured in both targets
- ✅ Extension has App Groups capability enabled
- ✅ Multiple
UserDefaultssuite names (bundle ID, bundle ID + suffix) - ✅ Delayed sync attempts in handler
- ✅ Comprehensive logging
Questions:
- What is the correct
UserDefaultssuite name for Safari extension storage on iOS? - When does
beginRequest()get called? Can it be triggered manually? - Is App Groups the right approach, or should I use a different pattern?
Alternatives I've considered:
- Deep link/redirect method (app opens Safari with token in URL)
- Content script intercepts URL and sends to background script
- Is this a supported approach for iOS Safari extensions?
Any guidance or examples would be greatly appreciated!