ScreenFloat

Let’s take a tour through ScreenFloat and see how it can power up your screenshots.

ScreenFloat for Mac – Your Screen Capture All-rounder

ScreenFloat Website (+ free trial)
ScreenFloat on the Mac App Store (one-time purchase, free for existing customers)
Eternal Storms Software Productivity Apps Bundle (ScreenFloat, Yoink and Transloader at ~25% off)

Posts in this Series

Part IHello ScreenFloat
Part IICapture – Take Screenshots and Record Your Screen
Part IIIFloat – Picture-in-Picture for your Screenshots and Recordings
Part IVEdit – OCR, Annotate, Crop, Fold, Resize, Rotate, Trim, Cut and Mute
Part VShare – Drag and Drop, Link Sharing, Export
Part VIStore – The Shots Browser, iCloud Sync, Tags Browser
Part VIIIntegrate – Widgets, Siri Shortcuts, AppleScript, Workflows, Spotlight

Part I – Hello ScreenFloat

ScreenFloat is a versatile screen capture utility that powers up your screenshots and recordings in numerous ways:

  • Capture screenshots, timed screenshots, recordings (with system and mic audio), your clipboard’s contents, or import photos, scans and sketches from your iOS devices (or files from Finder and other apps).
  • Float shots, so they’re always visible, like Picture-in-Picture. It’s a great memory aid, perfect for reference material, and gives quick and easy access to ScreenFloat’s OCR capabilities and other features, like the color picker and quicksmart-redaction. Create powerful workflows you run on floating shots with a simple double-click.
  • Edit your shots. Add annotations and markup, crop, “fold”, rotate, resize, de-retinize, trim, mute and cut them. Quicksmart-redact text, barcodes and faces, or copy text and barcode content to your clipboard.
  • Share effortlessly, by dragging the floating shot to other apps. Change formatting, sizing and quality options on-the-fly, and even decide if annotations should or should not be included. Create shareable and embeddable links for your shots with iCloud, ImageKit.io or Cloudinary.com.
  • Store, organize and collect your shots in the Shots Browser, and keep your Desktop clutter-free. Name, tag, rate, favorite and find them. Synchronize your shots over iCloud.
  • Integrate with macOS and other apps, using ScreenFloat’s Shortcuts, url scheme, and its AppleScript integration. Use Spotlight to find shots system-wide. Widgets make your shots, tags, folders and picked colors accessible system-wide.

Table of Contents


Getting Started

When you first launch ScreenFloat, you’ll be greeted by its setup screen that helps you set up keyboard shortcuts, iCloud sync, Spotlight indexing, and also – if you used ScreenFloat 1.x – upgrades your existing shots library to the new v2 format, analyzing your shots for texts, barcodes and faces along the way. (Depending on the number of shots you have, this might take a little while)

ScreenFloat is an app that runs in the background. More specifically, in your menu bar: you will not find it in your Dock, nor the app switcher (although you can, of course, drag ScreenFloat to your Dock manually).
You can access ScreenFloat any time via its icon in the right portion of your menu bar:

Using its keyboard shortcuts, menu bar icon, or widgets, ScreenFloat is always ready for you to capture your screen, or browse your Shots in the Shots Browser.


Capturing, Importing

ScreenFloat offers three types of captures: Screenshots, Screen Recordings, and Timed Screenshots.

Screenshots

To take a screenshot, use the according keyboard shortcut (by default, command (⌘) – shift (⇧) – 2), or select it from the menu bar icon. You can then select the portion of the screen you’d like to capture.

Recordings

Screen recordings can be started in the same fashion – by pressing its keyboard shortcut (by default, shift (⇧) – option (⌥) – 2), or via the menu bar icon. You have several recording options available to you – whether to highlight the mouse cursor, clicks, and key presses. You can also record your Mac’s audio output (speakers) and input (microphone).

Timed Screenshots

A timed shot is like a screenshot, only that it is taken with a delay. It can be very useful when you need to take a screenshot of something that takes extra steps to get to. You can take one by pressing its keyboard shortcut (by default, control (^) – option (⌥) – 2), or the menu bar icon.

Previously captured areas can easily be re-captured by press-and-holding the relevant keyboard shortcut.

You can copy the shot to your clipboard instead of making it float by holding the control key (^) on your keyboard when you release the mouse button for the capture.
Consequently, you can copy captured text to your clipboard right away after a capture, by holding the control (^) and command (⌘) keys pressed.

Import Shots

Importing files into ScreenFloat is easy. From Finder, you can right-click image and video files and select Open With > ScreenFloat, or Share > ScreenFloat. You can also drag them onto the app’s icon, or onto its symbol in your menu bar, or onto the Shots Browser. Or use a Siri Shortcut.

Tip: Did you know you can create shots of selected text from any app? It’s perfect for remembering stuff. Select some text, the click on the active app’s name in your menu bar and select Services > Create Shot from Selected Text. Alternatively, you can set up a keyboard shortcut for this in System Settings.app > Keyboard > Keyboard Shortcuts > Services > Text > Create Shot from Selected Text.
Or drag selected text to ScreenFloat’s icon in your menu bar.


Floating Shots

Shots and recordings you capture with ScreenFloat float by default. Floating shots float above other windows, and follow you around your apps and spaces, so the shot is always in sight. That can be very helpful when trying to remember something, copying info from one app to another, or as reference material.

While floating shots follow you around by default, there are more options available to you. You can pin floating shots to a space or fullscreen-app, so they will stay contained in that space, or only have them be visible when a specific application is frontmost.
When a shot is in the way, you can hide and unhide it (or all of them), or you can use “Work mode”, which hides floating shots as you mouse over them, and shows them again when the mouse exits.
You can change a floating shot’s opacity by scrolling up and down within it, and you can even make it ignore mouse clicks, so you can click through them (great for artists, for example).

Naturally, you can also close floating shots. They are stored in the Shots Browser, from where you can make them float again with a double-click.

Floating shots can be resized like any other window, by dragging any of its corners or edges.
A right-click or click onto the gear button gives you access to all editing, OCR and management features.

Option-right-click-drag onto a floating shot to use the color picker.

Set up powerful workflows you can run on your floating shots with a simple double-click.
You always resize a shot and reduce its dpi before you attach it to a new Mail? There’s a double-click workflow for that (and more):


Editing, OCR, Redaction, Annotation

ScreenFloat offers a wide range of editing options:
Resize, de-retinize, crop, fold, rotate, trim, cut and mute (you can remove all audio, or the system- and microphone tracks individually).
Annotate, redact and markup your shots with ease.

Every shot you take or import is analyzed for text, barcodes and faces, allowing you to easily copy and view that information, or quicksmart-redact it.

Redacting a line of text and a face in a floating shot, and Quick Look’ing a barcode.

Detected data is indexed, so you can find shots by a certain phrase they depict, or barcode content, within the Shots Browser, and Spotlight.

ScreenFloat lets you annotate, redact and markup your shots to your heart’s content.
Freedraw, rectangles, circles, lines, arrows, stars, checkmarks, x-marks, Text, Smart Numbered Lists, Highlights and Redactions are available to you.

Cutting your video recordings allows you to remove middle sections of your recordings entirely, or just parts of individual audio tracks:


Share

It couldn’t be easier to drag a shot to other apps. Start a drag from the floating shot’s document button, or by long-pressing the shot, or open the on-the-fly options menu and change the format, resolution, dimensions, and whether annotations and metadata should be included.

(You can also Export your shots for even more control).

Link Sharing

A file is too large to send, or you want to send multiple shots at once? Use iCloud Link Sharing to create a download-link, valid for 30 days.
You want to embed an image or video in a Markdown document, or a website? Use ScreenFloat’s ImageKit.io or Cloudinary.com integration to create permanent, shareable and embeddable links:

You want to share your Shot a different way? Use ScreenFloat’s Run AppleScript or Run Shortcut double-click action to upload the double-clicked shot to a service of your choice with an AppleScript or Siri Shortcut.


Store

Anything you capture with ScreenFloat, or import into it, is stored in the Shots Browser, where you can collect, organize, categorize and synchronize your Shots.

Give shots a name, tag, rate and favorite them. Move them into folders, or use Smart Folders to collect shots that match the rules you specify. An extensive list of detailed options is available, like whether the shot contains a barcode, or you have annotated it with a certain text phrase, to name just two.

You can synchronize your library (that means your shots, your folders, your tags, and metadata) via iCloud across your Macs, making your shots available everywhere your Macs are.

And you decide what gets synced – all shots, only images, or only recordings. Or only shots up to a certain file size.

To manage your tags, ScreenFloat has a Tags Browser, where you can rename tags, favorite, merge or delete them.


Integrate

ScreenFloat comes with a wide array of widgets and Siri Shortcuts, so its features are readily available to across macOS.

Control ScreenFloat from your Desktop or Control Center, or access your recent captures, picked colors, and more, with its Widgets:

Automate capturing and importing with Siri Shortcuts:

… or with ScreenFloat’s URL scheme.
Find shots with Spotlight, and run AppleScripts and Shortcuts with your shots using a double-click action.
Build custom workflows, executable on your floating shots with a simple double-click.


Up Next

The next part of this series – Part II: Capture – Take Screenshots and Record your Screen – takes a detailed look at all the capturing options ScreenFloat offers you. Definitely take a look, there’s a lot of neat stuff there!

Links

ScreenFloat Website (+ free trial)
ScreenFloat on the Mac App Store (one-time purchase, free for existing customers)
ScreenFloat Usage Tips

Eternal Storms Software Productivity Apps Bundle (Yoink, ScreenFloat and Transloader at ~25% off)
Contact & Connect


Thank you for your time. I do hope you enjoy ScreenFloat!

Read more

It’s been over a year and a half in the making (and so much longer since the last substantial update to the app), and now it is finally here.
I’m so very happy to announce the release of ScreenFloat 2, available now!

Re-written completely from the ground up in Swift and based on Core Data, ScreenFloat 2 keeps true to its roots – floating screenshots, and the Shots Browser – and builds upon them in multiple, very useful ways.

If you’d like to skip all the details and just download the trial or get the app from the Mac App Store, please feel free to scroll all the way down.

What is ScreenFloat?

At its core, ScreenFloat creates floating screenshots.
Think of it as Picture-in-Picture for your screenshots and recordings: it keeps information always in sight, no matter what window, (fullscreen-) app or Space you’re in.
It’s useful in so many ways: you want to remember something, you want to transfer information from one app to another, you want to keep a visual reference to something on screen – anything you can screenshot, you can float with ScreenFloat.

In the Shots Browser, your shots are stored and organized.
It keeps your desktop clutter-free and your shots always at your disposal.

What’s New with ScreenFloat 2’s Floating Shots?

ScreenFloat 2 brings a lot of changes to floating shots, so here are the most important ones.

+ Screen Recordings
A floating screen recording

Not only can ScreenFloat 2 take screenshots, it can also record your screen, together with (optional) microphone- and system audio. Of course, these recordings can be floated and interacted with, like you would any other screenshot.
They can be trimmed, rotated, cropped and muted. Still-images can be easily extracted.

+ Text-, Face- and Barcode Detection
Copying text detected in a Shot, quick-redacting faces and text, and viewing a QR code’s contents is easily done.

Every shot you take is analyzed for text, faces and barcodes.
It’s so easy to view the contents of a QR Code (supported are urls, calendar events, vCards and more), or quickly redact information, with a simple right-click.

+ Annotation, Markup and Redaction (non-destructive)
Annotations, Markup and Redactions in action

You can add annotations and markup to shots: freedraw, rectangles, ovals, lines, arrows, stars, checkmarks, x-marks, text, smart enumerated lists, highlights and redactions.
All of this is non-destructive. That means you can always come back and make changes, or delete them all and revert to the original image.
Double-click a tool or an annotation to edit its properties, like line weight, font, or color.

+ Crop, Rotate, “Fold”, Resize, “De-Retinize”
By “folding” a shot, you can remove a middle section of it, and the remaining two parts get stitched together.

Crop shots, rotate them, “fold” them(see video above), and resize them effortlessly.
Reduce a shot’s resolution from its “retina” dpi of >= 144 to 72 dpi when you want to save some space, or know you won’t need the higher resolution going forward.

+ Quick Drag
Dragging from floating shots has become much more useful

Drag a floating shot’s document icon to any app to share the image as you see it via drag and drop.
Or click the document icon, and get access to quick export options so you’re able to drag out a different format, at a different quality, “de-retinized”, at a different size, and with or without annotations/markup.

+ Color Picker
Pick colors from floating screenshots and -recordings.

When you option(⌥)-click-drag on a floating shot, the color picker will appear. When you release the mouse button over a pixel, you’ll be able to copy that pixel’s color’s values, a color sample image, and even drag out the color onto a target in another app.

+ Double-click Action Workflows

Set up custom, keyboard-modifier-key-based double-click workflows, like:
– Reduce the floating shot’s opacity to 40% and make it ignore mouse clicks
or
– Edit the shot with annotations, and when I’m done, upload it to iCloud(see above)

What’s New in the Shots Browser?

Apart from adding the ability to rate and favorite shots, here are the most important new features in the Shots Browser.

+ iCloud Sync

Your shots, tags, annotations/markup and metadata are synced over iCloud across your devices.
You have the last say over what gets synced, though: all shots, only image or video shots, or only shots up to a certain file size.

+ Privacy

With Privacy enabled, your Trash and any folder that may contain hidden shots require authorization before you can access their contents.

+ Smarter Smart Folders, Search, System-Wide Spotlight Search

Smart Folders come with a lot of new criteria for you to find just the shots you’re looking for.
These are also available in the Shots Browser’s search.
Shots are (optionally) indexed with Spotlight, so you can find them system-wide.

(Spotlight) Search and Smart Folder criteria not only find attributes you give your shots (like filenames or tags), but also what’s in a shot, like texts, or barcode contents.

+ Tag Browser

With the Tag Browser, you rename, favorite, merge and delete tags, so you can keep things clean, neat and organized.

+ Exporting, Sharing

Export shots in the format, quality, size and resolution you need. With or without annotations and metadata.
Upload multiple or large shots to iCloud and share a link to that, instead of attaching a large file.

What else is New in ScreenFloat 2?

+ Siri Shortcuts

Automate taking screenshots, timed screenshots and recordings with Siri Shortcuts. Add a title, notes, tags, and move them into folders, all in one go.

+ Widgets

Access your shots, folders, picked colors and more with ScreenFloat’s widgets.

Availability and Pricing

Alright, let’s get down to the nitty-gritty.

– ScreenFloat 2 requires macOS 12 Monterey or newer.macOS 13 Ventura or newer required for recording your microphone/system audio alongside screen recordings.
– A (free) iCloud account is required if you wish to have ScreenFloat synchronize your library across your devices.

ScreenFloat 2 is a free upgrade for existing customers of the app. If you’d like to support my work beyond its one-time purchase price, there’s a completely voluntary and optional tipping mechanism (in-app-purchase) available in ScreenFloat 2’s settings.

There’s a free, 28-day trial for you to download here (direct download link)
You can purchase ScreenFloat exclusively on the Mac App Store at USD 6.99 / EUR 7,99 / GBP 6.99 for a limited time, then the price will go up to USD 14.99 / EUR 15,99 / GBP 14.99.
It is at this time localized into English, German and Chinese (Simplified).

Downloads and Links

Download the ScreenFloat 2 28-day free trial
Download the ScreenFloat 2 Press Kit

Visit the ScreenFloat 2 Website
Check out ScreenFloat 2’s Usage Tips
Get to Know ScreenFloat 2 – Blog Series

ScreenFloat 2 on the Mac App Store
Eternal Storms Software Productivity Bundle (save ~25% on ScreenFloat, Yoink and Transloader)

Eternal Storms Software YouTube Channel

Contact & Connect
Eternal Storms Software Privacy Policy

Support / Feedback / Questions

If you have any questions or feedback, please do not hesitate to write me.
If you’d like to review ScreenFloat 2 in a publication of some sort (blog, news site, podcast, etc), you’re more than welcome to write me and I’ll get you the information you need.
I do look forward to hearing from you.

I hope you’ll enjoy ScreenFloat 2. I couldn’t be happier it’s finally out!

Read more

icon’t think of any more icon jokes

ScreenFloat lets you keep visual references to anything you see on your screen floating above other windows using screenshots. It’s also a screenshot organizer.

I’m now working on ScreenFloat 2, and I thought it would be fun to chronicle my progress, struggles, successes, failures and break-throughs, as well as random stuff while developing it.

Disclaimer: Estimated Time of Arrival, Pricing

I don’t have an ETA. I’m a solo developer, with multiple apps that need maintenance and updates, there are just too many moving parts for me to be able to estimate, well, basically anything. And while that may be a serious lack of managerial skill: I accept that flaw and ignore it 🤷‍♂️.

Regarding pricing, I don’t know what ScreenFloat 2 will cost yet. But I am resolved on its upgrade path: existing customers of ScreenFloat 1 will receive ScreenFloat 2 for free.

Entry 4 – Roadblock: Deadlock

It’s been quiet in this journal recently. The reason’s twofold.
1) I’ve been busy making good progress on the app and didn’t want to interrupt my flow.
2) I encountered a deadlock issue in my Core Data stack that I’ve been trying to debug for the last one-and-a-half weeks (and never solved directly, but found a way around it).

So much has happened and changed, though, so it’s high time I give an update.

Floating Shots

I reworked the floating shots a bit. If you recall, I had a few kinks to work out regarding the floating shot’s framing.
I reconsidered my approach and instead of using a window below the actual shot content’s window to act as the framing that holds the buttons, the entire thing is just one single window now, and with that change, I was able to get rid of all the issues I had.
Getting the resizing of a floating shot was a bit of a hassle: the image itself has a different aspect ratio than the “outer” framing window. However, the user resizes that outer window, not the shot itself, so the resizing has to take that into account. Nothing a bit of trial-and-error couldn’t fix; I ended up with an aspect ratio NSLayoutConstraint on the image that does the heavy lifting for me. The only downside is that if the image’s width is larger than the image’s height, resizing the window from its lower or upper edge won’t work. Conversely, if the image’s height is larger than its width, it can’t be resized from the sides. Thankfully, resizing from the corners always work, so it’s not a deal-breaker, but it’s something I’ll investigate further later down the road.

The wide image on the right can be resized from its corners and sides, but not from the top and bottom.
The tall image on the left can be resized from its corners and the top and bottom, but not from its sides.
Shots Browser

I defined my first milestone in ScreenFloat 2’s development to be “feature parity” with ScreenFloat 1.
That’s the thing about complete re-writes (which ScreenFloat 2 is – see journal entry #1 for my reasoning): you’re spending a *lot* of time re-implementing stuff that’s already there and works.
That can be frustrating at times, because you’re not making any progress on those cool new features you want to implement with the new version. But it can be equally rewarding, because you get to improve upon what’s already there, and use all the experience you’ve gained since implementing the original.

Now, as part of the “feature parity” milestone, the next step for me was to get started on the Shots Browser.

Work-in-progress UI of ScreenFloat 2’s Shots Browser

It’s your basic three-pane-setup.
The left pane is your source list. It consists of app-defined folders (like “All Shots”, “Favorites” and “Recently Deleted”) and (smart) folders you can create.
The middle pane shows shots contained in the folder you selected in the source pane.
The right pane shows information about the currently selected shot (if any).

The source list is an ordinary NSOutlineView, and has been improved quite a bit already in this early stage over its v1 counterpart.

Folders can now be duplicated, and its contained shots exported via the contextual menu.
You can also drag out folders – for example, to Finder – which will trigger an export of the contained shots to the dragged-to destination.
Aside from deleting the folder, you can also hold the option (⌥) key to show the alternate option, which deletes the folder, and all its contained shots.

ScreenFloat 2 defines a couple of smart folders for you, like “Favorites” or “Floating Shots”.
Hover over the Library header, and you’ll be able to add and remove any you want or don’t want:

For each of those, you can change just what “Recently” means to you:

Apart from the app-defined folders, you can create your own (smart) folders.
“Normal” folders just hold the shots you add to them, whereas smart folders automatically populate themselves according to rules you set up for them:

Localizations are not yet in place, that’s why it says tags.value, or tags.@count

I’m very happy with the tag suggestions feature. It serves up tags in the following way:
First, it displays tags that *begin* with the exact string you typed.
Second, it displays tags that *contain* the exact string you typed, *anywhere* within the tag.
And lastly, as you can see in the video, where I type “ysmt” and it serves up “yosemite”, it does a bit of regex matching.
With all that searching going on, I figured it would make sense to split that up into multiple threads (each search on one thread). However, as it turns out, that’s actually slower than doing it one after another – instead of 0.0002+ seconds, it takes 0.0003+ seconds per search. Maybe with a gazillion of tags, multi-threading would be the way to go, but I decided against it for now.
Instead, I’m doing some smart caching, where any subsequent search only operates on the result of the previous search, so if you type “y”, all tags are filtered for “y”. Then you go on to type “o” (entire string now would be “yo”), and it will only operate the new search on the already existing result from the “y” search. All results are cached for the duration of the creation of the smart folder, after which, it’s discarded, because tags are more likely to change then.

Smart Folder rules can become quite complex, and it’s something I’m looking into improving going forward, as those are directly matched against the Core Data shots library. In my testing, adding lots of tags to lots of shots, it can bring the Mac down to its knees (partly Core Data querying, but mostly my own current implementation of displaying the number of shots in a Smart Folder).
To improve that, I’m moving all boolean rules (like isFavorite, or isInCategories) to the front of the search, as those are much faster than string comparisons. This way, subsequent string searches would only be executed on a subset of the shots (i.e., only on shots that are a favorite), not the entire set, which would be the case if the string search was the first thing in the matching process.

I’ve also started work on importing shots into the Shots Browser. Obviously, taking a floating screenshot using ScreenFloat is the main way to get new shots into the app, but I also want to facilitate other ways and sources.
So the Shots Browser supports drag and drop for ordinary file drags, and promise file drags. It can also create a folder for you right away, depending on where you drag the files:

As a default folder name, ScreenFloat will attempt to pick up the app’s name you dragged from.

Enough about the source list. Let’s move on to the middle pane: the shots list.
Not much UI work has gone into this yet, but behind the scenes, a lot has changed.
ScreenFloat 1 uses IKImageBrowserView, which served me well, but it’s about to be deprecated by Apple, and it’s recommended to switch to NSCollectionView instead, so that’s what I did.
I have a rudimentary system for displaying shot previews set up, but it’s not finished yet and can take up quite a bit of memory right now, but that’s obviously just for now, while I get things going.
For shots to be displayed, I look at my app’s thumbnail cache and see if I have an image cached. If not, I look at the app’s Caches directory to see if I’ve already created a thumbnail in the size I require and load it from disk. If not, I create a thumbnail from the original image (because it’s usually smaller than the original shot), save that to disk (so I don’t have to do the thumbnail creation again later) and load it into the app’s cache (so I don’t have to read it from disk every time I display the shot).

I don’t know if resizing the previews is necessary (although it is available in ScreenFloat 1), but I probably will implement it in ScreenFloat 2, too. It’s just a bit of additional work because IKImageBrowserView allowed for it more readily than NSCollectionView.

Moving on to the info pane.
It went through a couple of iterations:

The first version of the info pane
The current iteration

What I like most about it, if I may say so myself, is my custom implementation of a “compressible” date field. The smaller the pane gets, the less info the date shows, in order not to be cut off / truncated:

The date shows less / more info depending on the field’s size.
Please ignore the red stuff at the left – it’s a UI debug flag I left on for the NSCollectionView shots list.
Tags Browser

A new feature in ScreenFloat 2 is the Tags Browser.
While working on the migration from the SF 1 database to the new Core Data backed one, it occurred to me I had many duplicate tags, just spelled differently – uppercase, lowercase, with or without space, etc.
I wanted a way to edit (rename), delete, favorite and – most importantly – merge tags. That’s how the idea for the Tags Browser was born.

As you can see, I have both “cocoa” and “Cocoa”. Now I can merge them into just one (or an entirely new one), and the Shots tagged with those tags will update automatically, thanks to Core Data.

Bad Luck, Dead lock

You know how they say you’re insane when you do the exact same thing over and over, and expect different results?

Speaking of tags, I discovered an issue that drove me friggin’ crazy the past two weeks.

First, a quick note on what a deadlock is.
An app can have multiple layers of execution (threads).
Every app has at least the main thread, which is where UI work happens (for example, updating the Shots Browser’s Source List happens on the main thread).
For longer running tasks, it might be better to run them on a background thread, so that the main thread – and thus, the app’s UI -, is not blocked.
However, if the background thread requires the main thread to complete something, and the main thread requires the background thread to complete something at the same time, it’s game over. You’re done. Finished. Kaputt.

The yellow car will only drive if the blue car drives first.
The blue care will only drive if the yellow car drives first.
Deadlock.

And that’s exactly what I experienced. But that’s not the driving-me-insane part.
It’s that this only occurred sporadically.
A bug is fairly easy to figure out and fix if you can reproduce it reliably. You execute function A, and the app crashes. Good. Fix function A.
But if you execute function A a thousand times, and out of that, it crashes twice, what to do then?

I had my Core Data stack set up like this:

please excuse my handwriting. I tried, like, really hard, though.

Three contexts. Context A is on a background queue, which writes to disk. It’s good to have this on a background queue, in order to not block the UI/app if it’s a longer operation.
Context B is on the main queue, so I can populate the interface with objects’ contents.
Context C is on another background queue, if I have to fetch a lot of shots, for example.

When I save context C, it saves to context B (not yet to disk).
When I save context B, it saves to context A (not yet to disk).
When I save context A, it saves to disk.

So in order to save a change I have made on queue C, I have to save C, B and A subsequently.
And it works fine. Except when it doesn’t. I found that when I drag > 700 shots to one tag, context C and B save fine, but context A deadlocks. But sometimes, it works without a hitch.
Or when I create a new Folder with > 700 shots, and save from C to A and to disk, it deadlocks. But sometimes, it works without a hitch.

You know how they say you’re insane when you do the exact same thing over and over, and expect different results?
Well, what say you to this, Einstein!?

I thought it might be an NSFetchedResultsController (which is a way to automatically be notified about changes to objects in Core Data, simply put) that gets in the way, as it is updated behind the scenes by Core Data when saving occurs.
So I disabled them. Same result.
I then created a sample project, trying to isolate the issue, and sure enough, it happened there as well.

This sort of thing gnaws at me. It’s always in the back of my mind, because I can’t figure it out. I tend to fixate and get frustrated, and eventually end up thinking the project is doomed.

To vent, I took to twitter asking for help. And thankfully, I got a pointer, directing me to NSPersistentContainer (thank you, Frank Reiff and Steve Harris).
I did know about it, but for some reason I thought it was only available on macOS Big Sur (11.0) and newer. I was wrong – it’s available on macOS Sierra 10.12 and up.

It does things differently, and it solved my deadlocking.
Instead of having one context writing to disk and child contexts on top (see drawing above), it has one main context (for UI work) which writes to disk, and offers backgroundContexts, which also write to disk directly. The way it’s set up, though, is that when you change something in a background context, the main context is notified about it and also has those changes more or less right away.

Now I must admit, I don’t know Core Data well enough to understand why I deadlocked before. And after almost two weeks of trying to understand, I really don’t care anymore.
I’m just happy it’s working now. I tried getting it to deadlock multiple times – with more than 700 shots dragged to a tag and saving – and it all works like a charm.

Fingers crossed.


That’s it for now.
It’s been tough – but any project eventually (and sometimes, repeatedly – yay) hits a point where I think it’s all over. At least, for me, that’s always been the case.
I guess, the lesson here is: no matter what happens, keep going. Don’t let it get you down too much. Ask for help if you need it, there’s always someone out there who’s been through it already, or knows something you don’t. And the Mac developer community is one of the friendliest and most willing to help there is.

Thank you for joining me. Feedback, input and questions are welcome: mail metweet me.
Take care! 

Read more