For one of my final CS classes, I was brainstorming a list of tech that I hadn't developed anything for or worked with, and screensavers on Mac were on the list as something that would probably lend itself to an easy short-term project. I had recently seen a series of animated gifs of automatic maze solving, and so I jotted a note to myself that it would make a cool idea for a macOS screensaver. And lo and behold, a few months later when I got around to it, it did! Without further ado, here it is in action.
I wanted it to be pretty customizeable, so I built in a series of options. With the settings pane, you can customize the maze color, solve color, time it takes to build the maze, time it takes to solve the maze, how large each square for the maze should be, how large the clock display should be, whether or not it should solve the maze after it finishes, and whether the clock is 12-hour or 24-hour.
For the most part, building a screensaver was pretty straightforward. They're primarily built in Objective-C, but I managed to find enough examples of them in Swift that I could use that instead. I ended up using SpriteKit to render the squares, and update them, and used a maze generating algorithm that basically just checks if it can "build" a path 2 squares in any direction, and then moves through a stack of those options randomly choosing directions, and backtracking if it runs out of places to go. During this process it also keeps track of the previous square, so that by the time it hits the end square in the top right of the screen, it has the solution, which it can use to trace it.
The one oddity was that the build order for the files was important. You had to make sure that the .swift file that implemented ScreenSaverView was the first one built, or Preferences would send function commands to random other classes, that would obviously crash. Given that only one class implemented ScreenSaverView, it was a little weird that this would be the case, especially given that you identify the class in question in the Info.plist file, but once I tracked down the bug it was pretty easy to adapt to.