A Patrick O'Brian Atlas

May 17, 2020, 1:22 am

After I finished my atlas of all the Patrick O'Brian novels I thought it might be cool to see all the courses I plotted on a single world map. I am working on an Apple MacOS screensaver to animate the maps, but in the meantime, here is a rendering of all the voyages.

You can click on the image for a higher resolution view.

If you are wondering about the occasional breaks in the course lines? They are a result of sections of the story where I couldn't guess where Jack and Stephen ended up. In those cases I pick up their location again once I had a fair weather observation.

Permalink - Comments - Tags: Patrick O'Brian

Network Effect - Martha Wells

May 16, 2020, 12:26 pm

Just read all the Murderbot Diaries ok. Just do it.

Permalink - Comments - Tags: Books

Network Effect (The Murderbot Diaries, #5) - Martha Wells

May 16, 2020, 5:21 am

Permalink - Comments - Tags: Books

Gotham: A History of New York City to 1898 - Edwin G. Burrows, Mike Wallace

May 11, 2020, 11:26 am

Permalink - Comments - Tags: Books

Bundle.main.path forResource will return nil in a MacOS screen saver

May 3, 2020, 5:10 am

I thought it might be worth writing a quick post on something that had me stuck building a screen saver for MacOS in Swift.

If you have a file you include in your build target (like a SQLite database of map tiles) and need to open that file you might try something like this:

let stringPath: String? = Bundle.main.path(forResource: "satellite-lowres-v1.2-z0-z5", ofType: "mbtiles")

Because I am debugging my application in a regular MacOS app (that just shows my ScreenSaverView) this code worked fine when I was debugging. As soon as I built and deployed the actual screen saver bundle everything broke.

So at that point you might spend quite a bit of time trying to debug entirely unrelated tile loading code before realising that bundle.main.path forResource was returning nil, but only in the screen saver application.

The reasons for this is that MacOS screen savers are bundles loaded by the system screen saver application, so the path you get will be something like:

/Applications/System Preferences.app/Contents/Resources

So to get this to work (in both the test app and the screen saver app) you need to get the bundle via a class in that bundle:

let stringPath: String? = Bundle(for: type(of: self)).path(forResource: "satellite-lowres-v1.2-z0-z5", ofType: "mbtiles")

I am just using the ScreenSaverView class which works fine.

This all took a little longer than it should have to find because, this being my first MacOS app, I wasn't sure where debug logging was ending up. Turns out it all appears in the Mac Console application ("Console" in Spotlight). I also struggled a bit because the Console app, or something in the MacOS logging framework was making decisions about the sensitivity of variables I was logging. So logging something like this:

os_log("Location was ---> %s", stringPath ?? "We got nil for our stringPath")

Ends up in the logs like this "Location was ---> " which isn't very helpful. To tell the logging framework that you want to see those variables you can supply it to the format string:

os_log("Location was ---> %{public}s", stringPath ?? "We got nil for our stringPath")

Permalink - Comments - Tags: Development, Swift