It’s been a while. What have I been learning lately?
As an iOS engineer, I spend a decent chunk of my summer free time tinkering with side projects to get hands-on experience with the new APIs coming in the Apple ecosystem. The nice thing about side projects is I don’t have to worry about pesky things like “backwards compatibility.” I never really have a plan during these summer coding hours. I just work on things that seem interesting to me and that could benefit from the new APIs.
So far this summer, my focus has been my Permanent Marker app. Things I’ve done:
- I adopted the new SwiftUI data flow APIs (
@Observableand its ilk). My verdict: Easy to adopt, much easier to use than the old version, something I really wish I could use on projects that do require backwards compatibility.
- I’ve poked around in TextKit2. I think “TextKit2 on iOS 17 / MacOS Sonoma” is the answer to my how to do rich text lists question.
- I’ve turned the Mac version Permanent Marker into a SwiftUI + AppKit app, not a SwiftUI + Catalyst app. It’s helped me learn how to make an app feel “right” when running on the Mac.
- I’ve started using Apple’s Swift Markdown package and I’m working on a rich text editing component for my Markdown files.
- I don’t know if I’m getting better at SwiftUI, but I keep re-training my intuition on the “right” way to do things in a SwiftUI app. For example: As I said, Permanent Marker now has a rich text editor component. This is a SwiftUI wrapper around UITextView / NSTextView. The scenario: How do I get SwiftUI actions (“someone tapped the bold button”) to get recognized by the UIKit / AppKit code? If I was writing this as a UIKit app, I can just send the toggleBoldface() message to the UITextView instance. In SwiftUI, though, even when you bridge to UIKit classes, you don’t have a natural way to manipulate the underlying UIKit code. My first approach was to just dispatch messages to the responder chain, knowing my UITextView instance would get a chance to respond to that message. But later, I stumbled on an approach that feels more aligned with the SwiftUI style: I created an @Observable model object called CurrentSelectionFormatting, and I do things like toggle bold properties on that model object. I then update the text view in response to model object changes, not in response to messages. Is it better this way? I’m not sure. But it just feels more SwiftUI.
There’s still a lot I want to do with this app, but so far I’m really happy with the changes I’ve been able to make.