Safari Web Extension not receiving App Groups data from iOS app

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 SafariWebExtensionHandler reads from App Groups in beginRequest()
  • 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.local when 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:

  1. ✅ App Groups properly configured in both targets
  2. ✅ Extension has App Groups capability enabled
  3. ✅ Multiple UserDefaults suite names (bundle ID, bundle ID + suffix)
  4. ✅ Delayed sync attempts in handler
  5. ✅ Comprehensive logging

Questions:

  1. What is the correct UserDefaults suite name for Safari extension storage on iOS?
  2. When does beginRequest() get called? Can it be triggered manually?
  3. 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!

Safari Web Extension not receiving App Groups data from iOS app
 
 
Q