tl;dr PhotoSorter is a tiny macOS utility for sorting loose images into folders with keyboard shortcuts. I built PhotoSorter for myself a few months ago because I needed a faster way to clean up folders full of random images. By “photo library” I mean photos managed by Photos on macOS, Google Photos, or any other actual photo management app. PhotoSorter is for everything outside of…
It’s been almost three years since I set up Sonarr and Radarr on my NAS. Both do an amazing job managing my media library, and the setup has been rock solid. The only part I never enjoyed was managing the library on the go. If you’re building a similar setup, these posts might help: My Synology Setup Configuring Tailscale Subnet Routing to Access Docker Containers by LAN IP Setting Up…
Today I needed to convert a PDF to Markdown on macOS. I tried CLIs I could install with brew , but none of them gave me decent output for structure and formatting. marker-pdf was the first one that consistently gave me clean Markdown, even though it required more work to set up. I used this convert.py script: #!/usr/bin/env python3 import subprocess from pathlib import Path def…
Seeing RTNETLINK answers: Not supported during init-wireguard , or Error: Could not process rule: Not supported with add table inet hotio when starting ghcr.io/hotio/qbittorrent on DSM 7.2/7.3? That’s Synology’s 4.4 kernel lacking nftables support after hotio dropped legacy iptables workarounds. Typical failure logs look like this: [VPN] Creating interface [wg0-fix]. RTNETLINK answers:…
Cisco Umbrella can block domains by returning fake DNS answers, which makes a site look down even though it works elsewhere. If you only need access to a few domains, bypass the DNS layer for those domains on macOS. ⚠️ Disclaimer: This guide is for educational purposes. Bypassing corporate security controls may violate your company’s IT policies. Use responsibly and at your own risk.
Mail popped up an alert: “Mail cannot save information about your mailboxes because there isn’t enough space in your home folder.” My first two suspects in these situations are always Xcode junk or a full Trash. I opened OmniDiskSweeper and started scanning. I love it because there is no visual fluff. You scan, you delete, you move on. I cleaned up old runtimes, old Xcodes, and VM images. That…
A dependency mirror refers to an alternate source location which exactly replicates the contents of the original source. [1] I often end up in the same situation: I need to tweak an internal package that a project depends on. The usual options are: Drag and drop the repo into Xcode (Xcode replaces the remote dependency with the local copy) Change Package.swift to a local path dependency Both work,…
tl;dr Instant Platinum v0.1.0 released! 🚀 Instant Platinum is an unofficial client for Fitness Platinum. The audience is tiny: a gym franchise in Kraków and Katowice, Poland. That’s fine. This is mostly for me. I can’t stand the official app. It’s not terrible, but it’s bloated with things I don’t care about: booking classes, managing goals, shopping (??). I just want to see my entry QR code as…
Platinum Pulse is a web app that aggregates live occupancy data for Fitness Platinum clubs . Small disclaimer: the audience here is tiny. Fitness Platinum is a gym franchise in Kraków and Katowice, Poland. I recently built a tiny iOS app to instantly generate the gym QR codes I need. “Doesn’t your gym have an official iOS app?” It does. It’s just bloated with things I don’t use: booking classes,…
Problem? I wanted to get notified about new openings as soon as they come up. Even though I’m only interested in a handful of companies, manually checking each careers page gets boring pretty quickly. I’m aware there are some paid tools that solve this exact problem (hello Fluxguard , Versionista ), but I’m too cheap for that. In this short tutorial, we’ll set up monitoring using a…
You have a website built with Hugo hosted on CloudFlare Pages and you want to integrate Decap CMS to it? Here’s how. At the end of this article you’ll be able to add posts to your website and manage existing ones using a Decap admin panel on your website. Prerequisites Your website is built using Hugo Your website is hosted using CloudFlare pages You have a GitHub account (we’ll…
A few months back I migrated my notes from Bear Notes to Obsidian. The switch has been great - I love what Obsidian offers. One feature I missed dearly from Bear Notes was the ability to quickly navigate between notes using up/down arrow keys. This couldn’t be replicated using Obsidian hotkeys or plugins, and other people were missing this feature too. Turns out Obsidian just added this in…
Need your Alfred snippets on iPhone and iPad? Alfred Snippet Converter now supports zip archives, drag & drop, and batch conversion of multiple collections. What’s New Zip Archive Support - Convert collections directly after exporting from Alfred without manual extraction. Drag & Drop - Simply drag your collection files onto the app window. Batch Processing - Convert all your Alfred snippet…
Seeing a red dot with “401 unauthorized” status for Plex in your Homarr dashboard, even though your Plex server runs perfectly fine? The issue is likely your URL format. Instead of using the standard IP:PORT format like other containers, Plex requires the full web interface path. The Fix Change your Plex internal address from: 192.168.1.100:32400 To:…
When using Cursor’s Vim plugin on macOS, you might notice that holding down keys like j or k for navigation doesn’t repeat as expected. Instead of continuous movement, the system shows accent character options or simply doesn’t repeat at all. This happens because macOS has “Press and Hold” enabled by default, which interferes with Vim’s key repeat functionality.…
I’ve been running various Docker containers on my Synology NAS for years, and while Tailscale has been excellent for accessing the NAS itself remotely, I found myself frustrated by one specific limitation: I could only access my Docker containers by their LAN IP addresses when I was actually connected to my home network. When I was away from home, even though I could reach my Synology via…
Setting up a reverse proxy on your Synology NAS can dramatically improve how you access your Docker containers. Instead of remembering ports for each service, you can use clean subdomains like plex.yourdomain.com or radarr.yourdomain.com . What’s Caddy? Caddy is a modern, open-source web server that excels at reverse proxying. It’s lightweight, easy to configure, and handles HTTPS…
A few months ago, I decided to try Xcode’s new buildable folders feature in my project. However, right after converting all my groups to folders, I discovered that CocoaPods had stopped working. Attempting to install project dependencies resulted in the following error: $ pod install ❌ ArgumentError - [ Xcodeproj ] Unable to find compatibility version string for object version ` 70 ` . At…
Learn how to install MeTube, a web GUI for youtube-dl, on your Synology NAS using Docker. Follow this step-by-step guide to automate downloading YouTube videos directly to your Plex media library.
I recently needed to add Swift Package Manager support to a legacy package that one of my projects was using. The package was originally distributed with CocoaPods. The primary reason for migrating from CocoaPods to SPM is that CocoaPods entered maintenance mode a few months ago. Removing it will future-proof our projects and allow us to use the latest features, such as the buildable folders…
Note: This article was originally published 05/2025. Last update 08/2025. Changes: Added sockpuppetbrowser to enable Playwright Chromium/Javascript fetch method Changedetection.io is a powerful open-source tool that monitors websites for changes. It’s incredibly useful for tracking updates on pages that don’t offer their own notification systems. This guide will walk you through…
Prerequisites Before you start, you should have qBittorrent up and running using this guide. Implementation If you’ve used the guide linked above, the qBittorrent container is already running. There are two configuration files that we’ll need to edit: .env and docker-compose.yml . .env Make sure the LAN_NETWORK variable is set properly. If you haven’t modified it after the…
I’ve mostly moved away from using Objective-C over the years. While it still appears in some of the projects I work on, it’s been quite some time since I last had to work on a feature written entirely in Objective-C. These days, I typically encounter it when integrating a new feature written in Swift into an older codebase. Recently, however, I needed to brush up on Objective-C for a job I…
My current project has a single target and multiple schemes. Each scheme represents the same app for different countries/regions. It’s essentially the same application with minor adjustments made for each of the supported jurisdictions. In Xcode projects, you define supported languages at the project level (not scheme level). Because of this structure, each app variant inherits the same…
Update: 26/03/25 It looks like Objective-C is still an option in the default iOS project template. You can access it after setting the Interface to “Storyboard”. I hadn’t realized these dropdown menus were interconnected. All credit goes to Douglas for spotting this! tl;dr use macOS → Application → Game or Command Line Tool Recently I wanted to refresh my memory on Objective-C.…
I’ve noticed that the SwiftLint plugin can add up to 30 seconds to incremental build times. In my case, it nearly doubled the average incremental build time! Since there’s no straightforward way to disable SwiftLint across all local packages in a project, I decided on the simplest solution: automating the process of temporarily commenting out SwiftLint from the dependencies list. In my…
Homarr creates a customizable browser homepage that lets you manage and interact with Docker containers running on your homeserver. Here’s my dashboard setup: Prerequisites Docker installed on your system (follow this Synology setup guide ) Installation Append this configuration to your docker-compose.yml file: homarr : container_name : homarr image : ghcr.io/ajnart/homarr:latest restart :…
In this article, I’ll show you how to access a web page’s content, alter it using JavaScript, and display it using your Safari extension’s UI. Specifically, I’ll demonstrate how to display an article’s content in a popover. I often use Large Language Models (LLMs) to summarize articles when I’m unsure if they’re worth reading. Without the extension…
I run qbittorrent in a Docker container on my Synology NAS, with VPN configured at the Synology system level (Control Panel -> Network -> Network Interface) rather than the container level. For setup instructions, you can follow this guide . Even with killswitch enabled, I wanted to verify beyond the UI’s “Firewalled” status that my torrent traffic was actually routing through…
I’ve been using Synology for the past year, and during this time it’s become the center of my home computing. I’m still discovering new use cases, so I’ll keep this post updated. Today, I want to share how I ended up with this setup - the how and why. Here are the main things I use my NAS for: Media Server - My Synology stores and serves my entire collection of movies, TV…
For years, I wanted a way to launch my most-used apps with single-key shortcuts. While I knew tools like Hammerspoon could make this possible, I never found a key combination that felt right. I’d always end up disabling the setup, missing the functionality of keys like right control, caps lock, or escape. Everything changed when I discovered Karabiner Elements’ ability to create…
Setting up AdGuard Home as a Docker Container on Synology NAS In this guide, I’ll walk you through the steps to set up AdGuard Home (AGH) as a Docker container on a Synology NAS. This setup will allow you to use AGH both inside and outside of your home network. AdGuard Home is a network-wide DNS server that blocks ads and trackers for all devices on your network. It filters unwanted content…
tl;dr: If your custom DNS does not work in Safari, you might want to try disabling Advanced Tracking and Fingerprinting Protection. A few weeks back, I set up AdGuard Home on my Synology NAS. I’ve been using it without any issues inside and outside of my home network thanks to Tailscale. There was one issue with this setup though: battery drainage on all of my mobile devices. I noticed that…
In this article, I’ll describe how to set up your Plex server so you can access it remotely through Tailscale, with Remote Access completely disabled in Plex server settings. Prerequisites Have a Plex server running as a Docker container using this guide . When you’re done, you should have a docker-compose.yml and a .env file with all your environment variables. Have Tailscale set up and running…
When adding a local Swift package to your Xcode project, you might encounter the following error: Missing package product `PACKAGE_NAME` The issue often occurs when the package you’re trying to add is already open in Xcode. To resolve: Close the package in Xcode. Close your main project. Reopen your main project. I’m not sure what might be causing this issue or why reopening the…
tldr: In order to keep the current Safari window open when you close the last tab, use tab groups. Last month, I once again switched my default web browser to Safari. It has its quirks, but I missed it in a weird way. I initially switched to Firefox because of its stellar support for vim keybindings and some other extensions I started to enjoy. Even with all those improvements, I began to miss…
In my current role, we have around 30 projects distributed across roughly 20 different repositories. Most of them are Swift packages for various features used in our apps. This setup requires me to frequently switch between multiple projects. Just a few days ago, I was working on the login flow. This involved modifying two Swift packages and one Xcode project. Remembering whether a given project…
I’ve noticed that I’ve been wasting a lot of time watching Instagram Reels lately. This would not be a problem if I actually enjoyed the time spent doing it. However, this was not the case. I’m not only angry at myself after the fact, but I also usually feel miserable while mindlessly scrolling. It’s just that sometimes I lack the discipline to avoid it altogether. Ideally, I’d completely…
Imagine you’re working on Project A, which relies on Package B, a remote Swift package. To incorporate modifications in B and assess their impact on A, the standard approach requires committing and pushing the changes in B, updating B’s version in A, and then rebuilding A to observe the outcomes. This method is slow and cumbersome. There must be a better way! Project A | └──> Swift…
This website uses the PaperMod theme for Hugo. The default setup offers a primary RSS feed for all posts at yoursite.com/index.xml . However, I needed more granularity—specifically, RSS feeds for posts tagged with certain keywords. After some exploration and experimentation, I discovered that Hugo automatically generates RSS feeds for each tag. TIL! Here’s how you can access these…
A few months ago, I wrote about Alfred Snippets on iOS . In that article, I described the manual process of converting Alfred text snippets into macOS text replacements. Since then, I’ve had time to refine this project and add some new features. You can download the final Command Line Interface (CLI) or the macOS app from this link. Next on my list is the complete automation of the process…
How to automate adding plugins to all of your existing (and future) targets in a Swift package TL;DR package.targets = package.targets.map { target in var plugins = target.plugins ?? [] plugins.append(.plugin(name: 'SwiftLintPlugin' , package: 'SwiftLint' )) target.plugins = plugins return target } The Problem Last month, I was tasked with adding SwiftFormat and SwiftLint to one of the projects my…
tl;dr this is currently not possible. See Solution. Last week, I was working on extracting functionality responsible for handling Live Activities into a separate Swift Package Manager (SPM) package. Apple introduced Live Activities with the release of iOS 16.1. My project’s deployment target is currently set to iOS 13. As you can imagine, this feature had lots of #if available checks. To…
My story begins with a quest for a reliable ad blocker for Safari. I used Wipr for years, but it started performing poorly. I tried AdGuard , but it required a root certificate for HTTPS traffic, which was a dealbreaker. PiHole seemed complex to configure, so I found NextDNS , a DNS-level content blocker promising effective ad and tracker filtering. I decided to try it. NextDNS: The Game Changer…
Last updated: 13/08/23 I’ve relied on Alfred as my daily driver for boosting productivity for years. However, I didn’t switch from Apple’s Spotlight overnight. It took three attempts before I truly embraced its capabilities. In this article I’ll share my Alfred setup and explain my most frequent workflows. Let’s dive in! The Initial Setup I’ve already described the initial setup in detail in New…
How to use GitLab’s built-in test coverage report tool for pure Swift packages? Some test coverage report generation tools do not support “pure” Swift packages. One example is Slather . By pure, I’m referring to packages that contain only the Package.swift file, without any .xcodeproj or .xcworkspace files. One solution to this problem was to generate a project file for a Swift package on…
I’ve been putting off this project for the past ~18 months. Most resources I’ve found focus primarily on US-based investors. Sadly, most of the assets listed in those resources are unavailable to investors located in other parts of the world. What came to my rescue was the Banker on Wheels blog. I did not find any other resource that came even close to this one. It was a one-stop shop for my use…
Last updated: 20/05/25 This note describes the steps I take when setting up a new Mac. This process could be mostly automated, but I can’t get myself to do it. It takes me around 90 minutes to go through all the steps. Let’s get started! I. Prerequisite Files to Import Before diving into installations, I make sure to have these configuration files ready: .gitconfig .zshrc II. Software Installation…
Development Assets in Xcode that allow developers to provide test data to use within SwiftUI previews and other code during development. Assets marked for development will only be included in debug builds and removed once you create an archive of your app. This solution is preferred to having larger assets in the production binary size. Developers can add different types of data as Development…
After installing macOS Ventura, I began experiencing connectivity issues when using MX Keys keyboard through Bluetooth. The keyboard would disconnect from my Mac whenever it was inactive for a few minutes. What made this issue especially frustrating was that it didn’t happen every time, and the time it took for the keyboard to reconnect varied widely. It drove me insane. I’ve been…