It’s becoming quite common for web developer blogs that show up on the front page of Hacker News to not have an RSS feed. This feels like a step backwards. I know RSS usage is not what it once was, but it seems like something you should get for free. Blogging platforms like WordPress (currently 43% of all websites) and even Mastodon support RSS out of the box. The Next.js blog demo automatically builds an RSS feed. There are popular RSS feed generator packages for every language.

For example:

Support the open web and make reading your blog easier!

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. 🤞