iOS16 and iOS17 were fine, but on iOS18, our Safari extension that blocks content via static rulesets randomly stops working. Frequently, when a tab is left in the background for a long time (i.e. hours), the content blocker will stop working (until I either kill safari, or reload the extension). I've debugged this and the background.js script reports the ruleset as being loaded, but nevertheless, our rules aren't applied.
I really don't think that it's an issue with the way that the rules are defined, since iOS16 and iOS17 worked fine, and on iOS18, the rules DO work. They just stop working after a while.
"declarative_net_request": {
"rule_resources": [
{
"id": "ruleset_1",
"enabled": true,
"path": "ruleset_1.json"
}
]
},
Some theories:
I have other content blockers on my phone that have LOTS of rules (adguard). Could I be seeing the effects of too many rules? Can I debug this somehow? Do logs get printed somewhere when the max rule limit is reached?
Does the use of private and regular tabs mess things up?
Please, any input is appreciated, as all of our logs are normal and error-free.
Post
Replies
Boosts
Views
Activity
My Safari Web Extension app for iOS sometimes exhibits an issue where the request to SafariWebExtensionHandler sometimes doesn't return.
This never happens on the simulator, and never happens when I'm actively debugging the SafariWebExtensionHandler process. It only happens on a physical device, and it only happens about 5% of the time. Note that the request happens RIGHT when the page loads (document_start), so I wonder if there's some kind of race condition happening, or a bug in iOS.
No errors are thrown, and I've pared back the logic to be extremely simple, and I still see the issue persist. I'm PRETTY sure it's the SafariWebExtensionHandler because I've tested bypassing it completely (returning a dummy response from background.js), and when I do, the issue never happens.
I've seen this issue posted before:, but without a resolution.
SafariWebExtensionHandler.m?:
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
NSExtensionItem *response = [[NSExtensionItem alloc] init];
response.userInfo = @{ SFExtensionMessageKey: @{
@"op2": @(YES),
@"op3": @(YES),
@"op4": @(YES),
@"op5": @(YES),
@"op6":@(YES),
@"op1": @(NO)
} };
[context completeRequestReturningItems:@[ response ] completionHandler:nil];
}
background.js (removed proprietary logic so excuse syntax errors):
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received request: ", request);
if (request.action === "getUserSettings") {
var payload = JSON.stringify({cmd: "getUserSettings"});
sendMessageToNative(payload, async function(response) {
sendResponse(response);
});
return true;
}
return true;
});
content.js
browser.runtime.sendMessage({ action: "getUserSettings" }).then((response) => {
...
});
I've worked around this by waiting for a few seconds and then resending the request if I never got a response (and this workaround works!), but this results in a bad UX. So, does anyone have any tips, pointers, etc?