Yesterday was the second day this week I managed to work on Stream for Mac.
Some things are starting to gel but as is typical I figure something out and run head long into the next thing I need to figure out. It’s all good stuff though! I’m definitely not complaining as I’m learning a lot and at least I should have a solid — very basic — understanding about the assembly of a Mac App when I’m done with this release.
Yesterday I managed to get the File Menu items hooked up and I did a very basic implementation of Import Subscriptions which allows you to import an OPML file of all of your feeds. For the first test the file name was hard wired to a file in the Downloads folder. There was my first challenge. I had to learn a little bit about the sandbox and setup the app to allow for read only access to Downloads, then ask the user for permission to access it. Once that worked I was able to start the import process by stubbing out some of my protocols used by the process and just allowing it to run in the background. It ran to completion and I was able to add an additional 206 feeds to my list. It’s a great way to populate the app!
Next Task
I’m trying to instantiate a class early on in the AppDelegate and I want to pass it down through all the various layers ultimately to the Feed View Controller. That’s where I got stuck once again. That’s ok. I’m learning and I may be doing it wrong. Right now the data I’d like to instantiate at startup is instantiated in the Feed View Controller. The reason I’d like to get it in the App Delegate is I’d like access to it when a menu item is selected. Maybe this is just flat out the wrong way to look at it? I don’t know yet, I’m still trying to decide what’s best.
First off I’m using Storyboards, which is the way the project was created in 2021 when I made the target. So, given that I’d like to programmatically load the WindowController, Window, and finally ViewController myself so I can pass this data all the way down to the ViewController. On iOS it’s a very straight forward process. Load the ViewController and specify the init method you’d like to use and provide parameters. Done, easy.
On the Mac there are two extra layers to go through which has me questioning my whole reason for existence. It seems really dumb to pass through two extra layers just to get to the ViewController. Perhaps I do need to rethink my entire existence? Perhaps I just need to rethink the structure of my existing classes to better accommodate the Mac?
Why, Rob, Why?
I’m doing this because the thing that kicks off the refresh process also takes an instance of a protocol that’s used to update progress of the refresh. It’s what drives the progress indicator you see in the navigation bar of the iOS app.
When someone selects the Refresh menu item it’s handled in the App Delegate. That is removed from the UI where the update needs to happen by two layers; Window Controller and Window.
On iOS the UI interaction is handled by the View Controller which kicks the process off right at that layer and provides an implementation of the progress protocol I’ve defined so the UI updates properly. If I didn’t want to update the UI the way I do it would be much easier. 😃 Perhaps the Mac App should do something different, like display a spinner and disable the refresh buttons and menu item until the process is complete?
Anyway. This is leading me to rethink a lot of my iOS strategies from years and years gone by to better suit the Mac and iOS platforms.
These notes are also really good for me. They help me think through the process as I’m typing and also lead me to say “Rob, you’re doing it wrong” a lot, which is also helpful to my learning process.
Overall I’ve had frustrating moments and really great ah-ha moments and I must say that the Mac and iOS communities have been so supportive of me and my stupid questions.
The Core Intuition Slack has been amazing! Thanks y’all, you know who you are! 🙏🏼