Blog

close

Bespoke Personal Software

Anthology

So… I wrote an RSS Reader. Why not? Everyone else seems to be doing it lately. I actually did it for the same reasons that I see other’s had written theirs. There wasn’t an RSS Reader out there that fit me perfectly. In my case I wanted something like Tapestry with its plugin connectors. What I didn’t want was the almost infinite timeline. I wanted a traditional 3 column RSS Reader like the OG of the group NetNewsWire. So I wrote Anthology.

You Can’t Have It

I think Anthology is pretty cool. It is a SwiftUI and SwiftData app that uses almost no AppKit or UIKit code. It runs great on macOS and iOS. The user interface is very similar to NetNewsWire but it uses Tapestry’s Open Source plugin connectors to provide access to RSS feeds, Mastodon, Reddit, and more. It has iCloud syncing.

I think it is a pretty strong contender or at least has a lot of potential. I have no plans on distributing it though. Not for sale and not Open Source. Frankly, I don’t want to deal with the hassle. Besides, the field is saturated. The last thing this world needs is another RSS Reader.

Built in Four Weeks

Nobody was more shocked than me about how fast Anthology came together. It started out as a proof of concept. I put together the basic UI to learn modern SwiftUI and SwiftData. I also wanted to see if the new WebPage API was up to the task. It took 4 or 5 days (I can’t remember) to get the basic UI together. Then I took a break from it to put Zavala 4.0 out.

Once Zavala was in Beta testing, I picked the project up again. I began using Claude Code to assist in getting it done. Once Apple integrated agentic programming into Xcode, I switched to that using Claude Agent. Man, what a force multiplier AI programming is. I hadn’t really given it much credence before and I was really shocked at how productive it made me.

I fleshed out the rest of the UI and persistence in no time. I didn’t vibe code it, but I sure used a lot of prompts. I quickly learned not to trust Claude to not litter my codebase with junk. I seem to have to remind Claude to clean up failed rabbit holes it likes to go down sometimes. I deleted Claude’s code and rewrote it. Sometimes I made Claude rewrite it. I did this for a couple of weeks. It felt a lot like working with a team of decent programmers who were good at taking direction.

Claude seemed to work best if it had an example to refer to. I used SwiftData CloudKit integration for syncing. It surprised me how well it worked to be honest. It still wasn’t good enough. It created duplicate articles and constantly got confused about if an article had been read or not. So I wrote a custom CloudKit integration for one entity and had Claude repeat the process for the rest. All in all iCloud syncing took about 5 days to get to 100%.

In the end, I would guess that Claude wrote about 80% of the code under my supervision. It’s not sloppy code either. I have no problem reading it. In fact it is better than a lot of human written code that I’ve reviewed and that used to be my job.

Is this the Future?

Will more people be writing complex pieces of software for just their personal use? Has AI lowered the effort and skill needed to create something really cool that much? I’m beginning to think so. Frankly, I had fun building Anthology. I enjoyed working with the AI. I could see myself doing something like this again. I think this is just the beginning of bespoke, personal software.

Building Zavala 4.0

I’ve been working on Zavala 4.0 off and on for the last 6 months. It isn’t a huge release or change in Zavala’s features. I think that is a good thing. I think Zavala is fairly mature as an outliner application. While there are things I would like to add in the future, there aren’t any really big outliner features that I think are currently missing and need to be added ASAP.

That said, there were some significant cosmetic changes and some good size changes under the hood in this release. So much so that Zavala requires the 26 versions of the operating systems to work. Zavala 4.0 is also not backwards compatible with previous versions of Zavala especially when it comes to iCloud syncing. Read on to learn why that is.

Fixing iCloud Syncing

Adding data syncing to any application is hard. iCloud helps with that somewhat, but it is still really hard to get right. Shoehorning a hierarchical data structure like an outline into a flat data structure like iCloud is super hard and I did not get it right the first time. While I did improve the reliability of the syncing code over the course of many Zavala releases, it was never quite right.

Corrupted Outlines and occasional data loss were the unfortunate result of not having syncing code 100% perfect. When dealing with synced data anything less than 100% perfect is unacceptable. This has been resolved in Zavala 4.0.

To do this I had to change how Rows are stored in the internal database as well as how they are stored in the iCloud database. This new solution works really well, but isn’t compatible with the old versions of Zavala. This is because the older versions of Zavala have no idea about the database changes and would corrupt the values if allowed to.

If I could have made this backwards compatible with older versions of Zavala, I would have. The best I could do is not allow Zavala 3.3.9 and 3.3.10 to sync with iCloud if a version of Zavala 4.0 had touched it. I did the best I could to prevent any data loss. Contact me using the Email Feedback option if you have problems. I will do everything I can to help you out if anything goes wrong.

Supporting Liquid Glass

Love it or hate it, Liquid Glass is the new design language from Apple for their latest operating systems. If you are an app developer and don’t support it, your app is going to look dated and out of place on the lates OS’s. Fortunately, I feel like Zavala is one of those kind of apps where Liquid Glass looks good and isn’t the worst at usability.

Unfortunately, it is very difficult to have a Liquid Glass version of your interface along side the legacy look and feel of previous OS versions. This is because you have to update to the latest API’s to correctly use Liquid Glass and some things, like the spacing of elements have been changed. Basically to keep backwards compatibility for OS’s before the version 26 ones, you need to maintain two different versions of the user interface code.

So I made the difficult decision drop support for previous versions of iOS, iPadOS, and macOS. This is particularly painful due to the fact that Zavala 4.0 can’t sync with Zavala 3.x or earlier. Basically you need to have all your devices up to date to use Zavala 4.0. My apologies.

German Localization

Outside English speaking countries, Germany has the most downloads of Zavala. This makes it the most likely candidate for localization.

The ability to do localization was added in Zavala 3.x by Stuart Breckenridge. Many thanks to him. Unfortunately, neither I nor Stuart are German speakers. I put out some feelers for someone to translate Zavala into German, but didn’t have any luck finding someone. So I turned to AI.

I used Claude Code to translate Zavala into German. I checked as much of the translations as I could and they look pretty good to me. Of course there may be mistakes in there that need to be corrected. I think the same would probably be true if I used a human for the translations.

Simplified Chinese Localization

We got a last minute contribution from SteveShi. He used some AI and did verified and corrected it himself. Many thanks to SteveShi for this contribution!

New Create Rows Setting

One way that various outliners differ is how they handle this scenario. You are at the end of a Topic line and hit return to create a new Row, but you have child Rows under the current one. Some outliners create the Row right after the current Row as a new child. This is how Zavala has traditionally done it. Some outliners create the Row at the same level as the current one, after the child Rows.

On the site Outliner Software I saw the user Satis mention that he found Zavala’s default behavior regarding creating new rows with child row confounding. After some discussion I saw things his way. I hesitate to add Settings to Zavala, but I think this one rises to the occasion. You can now specify which behavior Zavala does with the new Create Rows editor setting.

Zavala 4.0 is out now

Go and check it out. I’m pretty happy with this release and I hope you will be too.