Hush WKWebView

If you’re building an iOS app with webviews, you need to decide whether to use WKWebView or SFSafariViewController. The WebView version gives you a lot more control, but you can’t use Safari Extensions. On the other hand, the Safari version automatically gets some of the features of Safari like content blocking extensions, but customization options are pretty limited and it doesn’t support loading local HTML files.

In this demo, I’m going to walk through a simple Cookie Consent blocker in WKWebView using the Hush block list, a Swift library from the AdGuard team, and the WKContentRuleListStore class that was added way back in iOS 11.

First, download the Hush block list and add it to your project.

Next, load the file as a [String] that is split on newlines.

guard let path = Bundle.main.path(forResource: "cookiemonster", ofType: "txt") else {
    return "[{\"trigger\": {\"url-filter\": \".*\",\"if-domain\": [\"domain.com\"]},\"action\":{\"type\": \"ignore-previous-rules\"}}]"
}

let file = URL(filePath: path)
guard let rules = try? String(contentsOf: file).components(separatedBy: .newlines) else {
    return "[{\"trigger\": {\"url-filter\": \".*\",\"if-domain\": [\"domain.com\"]},\"action\":{\"type\": \"ignore-previous-rules\"}}]"
}

The fallback here is just a rule that doesn’t block anything.

After that, convert this list into something that WKContentRuleListStore can use with the AdGuard library.

let convertedRules = ContentBlockerConverter().convertArray(rules: rules).converted

And finally, compile the blocklist and add it to the WKWebView configuration.

WKContentRuleListStore.default().compileContentRuleList(
    forIdentifier: "ContentBlockingRules",
    encodedContentRuleList: convertedRules) { (contentRuleList, error) in

        if let _ = error {
            return
        }

        if let contentRuleList = contentRuleList {
            webview.configuration.userContentController.add(contentRuleList)
        }

        let request = URLRequest(url: url)
        webview.load(request)
}

And to prove it works, here is a before and after from Stack Overflow.

Wire Updates

There have been a handful of Wire updates over the past few months. I won’t go into details on all the updates, but some of the main ones are:

  • Article Previews: You get an excerpt, article length, and the Open Graph image if there is one.
  • All Unread & Today: Pretty straightforward — you can get a list of all unread articles or just the ones from today.
  • Read Later: You can flag articles as Read Later and they’ll be surfaced in this special feed.

It’s funny to look back at old release posts and see what the app looked like in the early days. Previously:

My only New Year’s resolution is to practice mindfulness every day. I have been a long-time subscriber to Headspace, but have had trouble making it a consistent habit. 🤞

ActivityPub is cool because we finally have an open protocol to post and subscribe and reply to content across apps.

Mastodon is not Twitter. I get why people think of Mastodon as open source or distributed Twitter, but it’s more than that. If you add ActivityPub support to your WordPress site, others can see the comments and reply from Mastodon! I think this will get more obvious as time goes on and apps like Tumblr start to implement ActivityPub support as well.