Bookish Development Diary, episode 6.
Call me an idiot (“Sam, you’re an idiot” - ed.), but whenever I try to use
UISplitViewController, I seem to get myself into a tangle. It doesn’t work the way I expect it to.
What I generally want is an index view side-by-side with a stack of detail views.
If I’m on a phone, or a horizontally-compact environment, I want the index to collapse onto the stack, so that there’s just one view. Tapping an index item here should push the detail view onto the stack, replacing the index.
Assuming that I’m not restoring the previous state of the app, this is how things should start in a compact environment. I definitely don’t want the app to start showing an empty detail view, and hiding the index 🤦🏼.
If the view is collapsed and some detail is showing, I don’t want to be able to pop up the index view, or slide it over the detail.
I just want to be able to pop the navigation stack to get back to the index.
This is not rocket science!
I’m sure that you can get
UISplitViewController to behave like this, but invariably I seem to end up having to jump through a lot of hoops to do it, and even then sometimes do it wrong.
I hit this situation yet again whilst working on an example viewer app for Datastore, so I started wondering how easy it would be to just throw it away and make something simpler…
Erica Sadun blogged recently about the trials and tribulations of upgrading a system with a long history of tooling on it.
(the link to that blog post seems to have vanished; I’m not sure if it’s been taken down or just moved, but it doesn’t really matter, as the post was just a prompt to me to write what follows)
This is a problem I could relate to, having been working with Macs since 1988, and over many years developed a large number of scripts, utilities and system hacks to make my life easier and more productive.
Fortunately (sort of), it’s a problem I’ve had to try to solve (or at least make easier), since I’ve regularly had to move between systems, and work on multiple systems at once.
At one point, whilst working on Football Manager, I was writing the low level cross platform libraries which had to build on the Mac, Windows, Linux, XBox 360, PSP and PS3! I had about three monitors on my desk, four or five machines under it, and was regularly booting into development environments for all of them. Fun times.
What I used to do for many years was have a single monolithic directory under source control, which contained all of my helpful stuff. This had a bootstrap script in it so in theory I could just fetch the repo to a new machine, and run the bootstrap script.
It was never quite that smooth, but worked, up to a point.
However, it got a little crufty. Over time, as I moved on, most of what was in it became irrelevant, but was still hanging around. Some bits of what was in it actually logically lived elsewhere, which once I’d moved the thing into git meant some dalliances with submodules.
Eventually I realised that what I needed to do was to modularise this big lump of stuff, so that I could still share common things between systems, and still set up a new system easily, but I could also just install the bits I needed on any given system.
This sounded awfully like a package manager! Unfortunately, the ones I was familiar with tended to be tied to the Mac.
“How hard could it be?”, I thought - foolishly - to make a really simple one myself. All it needs is the ability to download packages, and to run a little script inside a package to install/uninstall it.
And thus, XPkg was born.
It is very much a work in progress, and I wouldn’t necessarily say that it’s ready for other people, but Erica’s blog post reminded me that I had been meaning to tell other people that it existed.
Rather than repeat myself, I’ll let the Read Me file tell you more.
You may also be interested to know that not only is it written in Swift, it actually uses the Swift Package Manager as the transport mechanism for fetching the packages that it manages, and resolving dependencies between them.
Bookish Development Diary, episode 5.
It’s been quiet around here over Christmas, and I cut myself a bit of slack and didn’t really do a lot last week, but I’m back to it now.
Pretty much the last decision I made before the holidays was that I needed to develop some basic view classes for use with Datastore, and that they should live in a companion module (called DatastoreKit), as another published product of the Datastore package along with the Datastore module itself.
I also decided that this should go hand-in-hand with a test application, which is a separate project and a client of both Datastore and DatastoreKit.
Bookish Development Diary, episode 4.
A tale of how the last version of the Datastore was just right, but it turns out that the latest version is even righter.
As I mentioned in a previous post, I really enjoy the way an API evolves as one slowly figures out what it is supposed to do.
This process is continuing with Datastore, the database backend that I’m using for Bookish.
It’s perpetually humbling to realise just how unfinished that thing that you thought was finished actually is. For instance: it turns out you actually need API to delete records - who knew? 1
Something that I particularly enjoy is the moment where two concepts/classes/algorithms that you thought were separate reveal themselves to be two aspects of the same thing.
This seems to be happening with Datastore…
I might have fogotten to add one in earlier versions of the API. :facepalm:. ↩
Bookish Development Diary, episode 3.
In which our intrepid developer disappears down a deep rabbit hole, in search of the cleanest and most idiomatic way to express string constants in Swift1. Because, you know, stuff…
Sometimes it’s the little things that make me happiest.
In an open-ended system like Datastore, where any property can be assigned to any entity, I needed to be able to specify a property using some sort of key.
It turns out that there are a few ways of doing this…
If you’re a sophisticated user of Swift, none of what I’m about to say will probably come as a surprise. You may be bored or underwhelmed by this tale. Sorry! In fact, maybe you know a better solution? If so, please let me know. The solution I describe is was one of those things that I had to puzzle out over time when I started writing Swift - mostly by seeing other code that looked cleaner than mine, and figuring out what the difference was. I’ve been meaning to write it down explicitly for a while. ↩