I'm working on a Safari Content Blocking extension. I intend to show setup instructions if the extension is disabled and to show settings if it is conversely enabled. How can I determine if the extension is enabled by the user?
I've seen this method to detect if a custom keyboard is activated but there's no key on NSUserDefaults
that relates to Safari Content Blockers.
To change these preferences, choose Safari > Preferences, then click Websites. The settings you can customize (such as Reader and Content Blockers) are listed on the left. To apply a setting to a website on the right, first select the setting, then choose the option you want from the pop-menu next to the website.
Content blockers are app extensions that you build using Xcode. They indicate to Safari a set of rules to use to block content in the browser window. Blocking behaviors include hiding elements, blocking loads, and stripping cookies from Safari requests.
So the Content blocking is a feature of the browsers that allows you to block or hide all or some content in a webpage or site that you do not want to see, including images, ads, pop-ups, comments and plug-ins.
As of iOS 10, there is a new method in SFContentBlockerManager
to support this:
getStateOfContentBlocker(withIdentifier:completionHandler:)
And you call it like this (Swift 3):
SFContentBlockerManager.getStateOfContentBlocker(withIdentifier: "your.identifier.here", completionHandler: { (state, error) in
if let error = error {
// TODO: handle the error
}
if let state = state {
let contentBlockerIsEnabled = state.isEnabled
// TODO: do something with this value
}
})
You could utilize a SFSafariViewController
to load a custom website. This website checks whether it is able to show something that your content blocker should block. Then redirect to the respective custom url (success/failure) that your app previously registered for. You could even use a hidden Safari View Controller without animation to avoid any distraction from the user's perspective (as shown here). (I guess this technique is used by former content blocker Peace)
contentBlockerEnabled
) Use SFSafariViewController
to show a custom website and include the following rule in blockerList.json
:
{
"action": {
"type": "css-display-none",
"selector": ".blocked_selector"
},
"trigger": {
"url-filter": ".*"
}
}
Check for blocked content:
if($('.blocked_selector').css('display') == "none") {
// Content blocker enabled
}
Redirect to custom URL (success/failure)
application:openURL:options:
(success/failure based on called url)Following on from Tilo's hypothesis, I built the proposed solution. I wrote about what I learnt on Medium and you can grab the source files from GitHub.
TL;DR It works but only temperamentally due to the latency incurred of the content blocking rules database to update. A potential workaround is redirecting the test page to create an artificial delay.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With