Zhenyi Tan And a Dinosaur

Why History Book Doesn’t Have a Real Export Feature

By far the most requested feature for History Book is some way to automate exporting saved webpages, so users can import them into other archival services or Obsidian or whatever.

I added a simple export feature ages ago, but the SwiftUI modifier is very limited. When you’re exporting multiple files, you can’t even specify the file names. So you end up with names like Exported HTML text 1.html.

I tried adding AppleScript support to History Book, but I could never seem to get it right. I couldn’t find much information online. Even Apple’s. Especially Apple’s. It seems like a lost art.

My limited understanding is that to implement AppleScript support, you need to create an .sdef file, add a few keys to Info.plist, then implement a KVC object graph for everything you want to script, including NSApplication. Then you need to implement objectSpecifier for all the exposed objects.

Then when you actually try it, you realize you can’t just do it on the NSManagedObject classes. You’d have to write wrapper classes. I don’t know how many hours I wasted debugging the KVC plumbing, or trying different things with the .sdef file. I was never quite sure if I’d done it right.

Then if you sell your app on the App Store, the app is sandboxed. And I don’t know how to nicely get a sandboxed app to write to an arbitrary path. You can (I think) work around that with some entitlements, but there’s no guarantee App Review will approve them. Even if they do, the user experience is still stupid. You still have to tell the user to go to Settings, click this button, click that button.

Then I thought about App Intents. With Shortcuts you can get 80% of the way there with very little code. But you need macOS 13, and History Book (and my old laptop) still runs on macOS 12. So that’s out as well.

So my last resort is to find the SQLite file Core Data writes to, and write a tutorial about how to export the data from there. I never got around to writing it, until now. So here goes.