This documentation guide and the corresponding demo project show how the the Web Extension Handler can inherit from NSExtensionRequesetHandling and implement beginRequest to receive and reply to messages sent from the background script via browser.runtime.sendMessage().
The guide also mentions how browser.runtime.connectNative and SFSafariApplication.dispatchMessage can be used to send messages from the Handler to the background script, but the code is not in the example project.
Further, it seems that SFSafariApplication is not available on iOS.
How can I send a message originating from the Extension Handler to notify the background script of events coming from native code (e.g. UserDefaults changes)? Is polling from the background script the only option?
Post
Replies
Boosts
Views
Activity
I have a Safari Web Extension that communicates with its native App through UserDefaults within an App Group.
The WebExtensionHandler is also used to carry out other functions for the Web Extension on request.
I am currently troubleshooting a bug where a request from the Extension to the WebExtensionHandler remains unanswered.
The bug only occurs on physical devices, in the simulator, it always behaves as expected. When XCode is attached to the App or App Extension process, the bug also does not trigger. When the Console App is used to monitor events on the device, the bug also does not trigger.
Here is the code for the WebExtensionHandler:
import SafariServices
func respondWith(_ context: NSExtensionContext, string: String) {
let response = NSExtensionItem()
response.userInfo = [ SFExtensionMessageKey: string ]
context.completeRequest(returningItems: [response], completionHandler: nil)
}
class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
var sharedPrefs = UserDefaults.init(suiteName: "group.eu.waiyu.app")!
func beginRequest(with context: NSExtensionContext) {
let item = context.inputItems[0] as! NSExtensionItem
let message = item.userInfo?[SFExtensionMessageKey] as! Dictionary<String,Any>
switch message["type"] as! String {
// other cases...
case "get_config":
if let config = sharedPrefs.string(forKey: "config") {
respondWith(context, string: config)
} else {
let defaultConfig = message["defaultConfig"]!
respondWith(context, string: defaultConfig as! String)
}
default:
respondWith(context, string: "Unknown Message type")
}
}
}
Even though it appears that something goes wrong when accessing sharedPrefs when the bug is triggered, other requests are answered correctly (before and after triggering the bug).
As per some solutions to similar issues (https://stackoverflow.com/questions/38275395/failed-to-read-values-in-cfprefsplistsource-ios-10) I have tried different App Group IDs:
the main Bundle ID, prefixed with "group."
an ID different from both main bundle and extension bundle, prefixed with "group."
"group.TEAMID." prefix (TEAMID being the developer team id)
Is there anything I can try with regards to the code? Are there any other debugging workflows I can try that do not involve attaching to the device, that might allow me to capture more information about the bug?