I’m starting to learn macOS development and I’m a bit torn on SwiftUI. As someone who’s primarily done web development the last few years, and comfortable with React, SwiftUI is pretty appealing from the standpoint of being a similar mental model.
On the other hand, it doesn’t quite feel ready. SwiftUI seems to be missing enough components that I end up needing to know how to use the existing AppKit stuff with autolayout, or know how things work under the hood to debug SwiftUI oddities. On top of that, there are few resources out there for learning macOS dev specifically — tons of stuff for iOS, which sorta translates, but not perfectly. I’ve been learning from the Hacking with macOS book, which is very good, and plenty of trial and error.
The other ding against SwiftUI for Mac dev seems to be that it’s only supported in Catalina, and it seems an awful lot of Mac users have held back from updating, so the user base might be diminished.
Most of these seem like temporary problems, but as a newcomer to this world it’s hard to tell if it’s too early to commit to SwiftUI.
SwiftUI is definitely not yet ready, particularly on macOS. Under iOS it can get the job done depending on the app in question.
It's rapidly improving, though. The version of SwiftUI shipping in iOS 14 and Big Sur are massive improved compared to the current version. If Apple can keep that rate of improvement up, it will reach parity with UIKit/AppKit within another release or two.
It's not too early to "commit" to SwiftUI. Just remember that "committing" doesn't mean writing every last bit of UI code in SwiftUI. At this stage, I think the best approach is to be using both UIKit and SwiftUI, and use whichever framework is better for implementing whatever specific features you're implementing.
For example, say I'm presenting a modal with a simple form. I'd use UIKit's UINavigationContoller to present the modal view, and within the modal's view, I'd have a UIHostingController which encapsulates the SwiftUI-defined form user interface. I can define form layouts (and other simple layouts) much quicker in SwiftUI than I can in UIKit, so I'm finding SwiftUI to be very helpful in that regard.
You must commit to not use SwiftUI if you support an older OS. If your deployment target is last year or newer, then do you have the ability to pick and choose.
>The other ding against SwiftUI for Mac dev seems to be that it’s only supported in Catalina, and it seems an awful lot of Mac users have held back from updating, so the user base might be diminished.
The majority updates fast - even more so when a 2nd update (Big Sur) comes out, few will hold to before Catalina.
With macOS it makes no sense to "hold out" from upgrading long. You are either prepared to get on with the program and move on, or you're left behind, worse than e.g. on Windows etc.
On the other hand, this makes the platform faster to move forward, adopt new things, and keep a more consistent UI doing so (Windows still have 5-6 UI layers from previous APIs/decades, depending on the app you use -- even for internal MS apps, e.g. you can still open an ancient version of the control panel from within the current one).
In retrospect however this move made total sense. When they will start deploying custom silicon next year every application that run on Catalina will be able to run on the new ARM Macs.
From Apple perspective it's way better that Catalina take all the blame and not the new products and the technology they are betting on for the next decade.
Also developers that care about MacOS platform were even more incentivized to finally upgrade to 64-bits after the 10+ years deprecation warning so that more Apps will be ready on day one for custom silicon.
While maybe true 64bits was available for more than 10 year with Snow Leopard (10.6) being the last OS supporting 32bits architecture (and dropping PowerPC support At the same time). So let's say you could have seen this coming.
Yeah, it probably depends on the audience somewhat. I know other developers who have avoided Catalina up til now (and I was one myself, until I got a new MacBook late last year), so that’s in the back of my mind as I’m thinking about making a tool for devs.
I’ve got two iOS apps in the app store that are mostly SwiftUI with some UIKit, it’s definitely viable but I recently tried working on an idea for a macOS app I’ve had for a while and was disappointed. Big Sur improves things somewhat but I’d recommend learning AppKit as well. The approach I’m taking is to use the overall SwiftUI structure but wrap a lot of AppKit views for the crucial UI elements, I figured I can replace the AppKit pieces easily later on this way.
Do you have any recommendations for articles that explain how to include AppKit with SwiftUI? I'm new to iOS dev and have been building with Swift/SwiftUI almost exclusively, but not sure what's the right way here just yet.
Not really, unfortunately it's a lot harder to learn AppKit than UIKit due to the lack of online resources available. Try to find open source mac apps and read the source code and Apple's documentation are the only suggestions I can think of. I've seen a "Hacking with macOS" Udemy course that looks comprehensive although I can't recommend it as I haven't checked it out. With regards to wrapping AppKit views in SwiftUI the process is more or less the same as it is with UIKit.
I went pretty deep on swift mac UI development at some point but I was left disappointed. I've realized that building your own gui toolkit isn't that hard. Right now, I'm building my own toolkit in Rust with this Rust nanovg clone called gpucanvas https://github.com/cytecbg/gpucanvas.
UI programming - and GUI toolkit programming - is all about breadth. There’s a ton of things a UI needs to do, but most of those things are straightforward to implement, and there’s usually a plethora of lower-level libraries to compose in any given area. So, it does take a lot of work to implement a UI (toolkit) but not much of it is a stumper. And, many areas of UI toolkit functionality can be ignored or have low-quality implementation for a long time. For example, a hobbyist writing their own UI toolkit can ignore accessibility, but still end up with something usable by the hobbyist. Or, the initial implementation can use only absolute layout. Or, the initial implementation can use only a single fixed-width bitmap ASCII font.
I didn't say easy, I said it's not too bad. Look at this toolkit for example https://github.com/yushroom/Fishgui. Once you have rendering (which nanovg handles), you just need some hierarchy, event handling, windowing and layout and you have a basic toolkit.
I like the control a lot, with Cocoa, I felt really constrained sometimes.
A key point of a shared UI toolkit is that users can bring their knowledge from one app to another. A standard Cocoa table view or text view has tons of advanced behaviors: type select, keyboard shortcuts, etc. It's worth the user's time to learn these because they work in every app.
But apps where these don't work feel discordant and frustrating.
You won’t ever produce a perfect imitation. UIs based on third-party toolkits are always a pain, stuck in the uncanny valley. They look somewhat like they should, but have all sorts of quirks that break useability: text fields that don’t support standard shortcuts, weird layouts, wrong fonts, buttons that cannot be selected with the keyboard, etc.
That's not the problem, the problem is that I can define a system-wide shortcut from System Preferences and it really is system-wide... unless you don't use the native framework, in which case I'm out of luck.
There are an infinity of little things like this. macOS is powerfully integrated across the platform and you either play ball with it or you don't.
One that's pretty important is accessibility. You're leaving the blind, vision-impaired, and paralyzed users out in the cold, because macOS has a fairly complete system for all those users to make use of the operating system. But it won't work for an app that isn't native.
This is the precise reason I hate web apps with a passion. I want every app on my machine to behave predictably and have a uniform look and feel, not for every UI designer to be able to produce their own unique snowflake without regard for consistency.
A certain genre of apps, especially eg. digital audio workstations, manage to do this and also have a sizeable userbase. Ableton Live is an example here. It seems especially sensible if your design does actually have a bunch of controls you need custom rendering for.
Honestly, don't let these comments get you down. It's important to act strategically of course, so it doesn't make sense to over-invest in an idea succeeding. But it makes sense to do scoped experiments / proof-of-concepts. I don't think we're "done" with UI framework architecture design, people need to keep trying new things in the space. And I also don't think only Apple (eg. SwiftUI) and Google (eg. Flutter) are allowed to work on these things and we need to accept their gifts from above. Some times, a good quality here is almost not believing that something is too hard to do (while obviously also informing oneself about as much existing work there has been as possible to incorporate it into the experiments).
You should wrap native file dialogs. Text input direction isn't that big of a deal if your rendering supports it. Tree views are somewhat tricky but not that much harder than list views.
How well does it actually implement each platform L&F (specially the feel part), does data virtualization, UI designers, support for disabled people and respective assistive technologies?
Drawing buttons and windows is easy, the problem is the rest.
Does the lack of arthritic, farsighted Arabic speaking users factor into it not being too hard or is that whole mess already built into the underlying libraries?
UI platforms as a rule are always terrible, but there’s inevitably a whole lot of baby in the bath water.
Common, customizable keyboard shortcuts & behaviors across the entire OS are huge for people with arthritis that can’t use a mouse, Automator workflows that hook in and take care of repetitive tasks are common and eventually Siri Shortcuts will be available on macOS like iOS.
A custom UI would force them into “grid mode” on page 6 off the bat while it’s almost too easy if you just stay native, UI tests interact with the app through accessibility labels for example, and obviously we’re all testing, right?
Simply riding closely on the back of the behemoth that’s weirdly good about accessibility gets one very far, very fast.
Cross platform wasn’t even mentioned or implied in your original comment by the way, it was edited into the second one where you narrowed an “arthritic, farsighted Arabic speaking user” into “arthritic”.
I used to be very strongly in favor of cross-platform but I have come to realize that in a lot of cases that while it is true for us as developers that cross-platform is great because it means a bigger audience, it is easily worse for your users.
I’d rather pay $50 for a native macOS application that uses the UI toolkits offered by its platform and respects the conventions and the system as a whole, than to pay $5 for an application that allegedly does the same thing but which feels broken, sluggish and/or incoherent because its developers are making something cross-platform.
There are some exceptions to this – some developers do pull it off, and if what they make is both good quality and performant and the tool is offering something of exceptional value to me then I will use it. But in the general case, I will avoid the non-native experience.
All of that being said, I still think it is cool that people invest time in exploring making their own GUI frameworks. All I am saying is that it has a cost for the users a lot of the time.
I'm looking forward to when you can just build an app once and use it across iOS and Mac right out of the box. Catalyst seems like a good first step in that direction.
SwiftUI universal apps do this even better by automatically using the appropriate backing controls for the targeted platform — e.g. a SwiftUI `Button` translates to `NSButton` on macOS and `UIButton` on iOS.
I think it's ultimately what Apple intends to make the flagship way to develop on their platforms. Catalyst exists mostly as a way to pull existing iOS apps and iOS developers under the Mac umbrella.
I didn't speak to developing for macOS specifically. The tldr is that it's not quite production-ready but it's easy to mix SwiftUI with UIKit so you can adopt it incrementally. I really like Apple's vision for SwiftUI and they're catching up with missing features very quickly.
One thing I am a bit upset is how Apple approaches SwiftUI / Combine, as these two to me, are foundational pieces to the Swift language ecosystem. Particularly:
1. There is no way to bundle SwiftUI / Combine to the app so you can ship to earlier iOS versions, making development exclusively done on newer OS version. More over, for any bug fixes on SwiftUI / Combine, you have to wait for the OS updates for the fix. Just updating your Xcode is not enough.
2. While the SwiftUI required language features are all upstreamed to Swift language, and core developers have been patient to articulate why. If SwiftUI / Combine development was done in public (i.e. open-source), bug-fixes and language improvements will be much smoother.
To Apple, point 2 probably is a big leap. But they've done Swift open-source release, and it works relatively well with a sizeable open-source ecosystem on other platforms now.
These are good changes. “View builders” are quite powerful but it was always strange to be able to get so far so fast and then be hit by a weird limitation involving fairly basic logic. Fortunately, there are work-arounds.
I’ve ported a few different AppKit interfaces to SwiftUI “1.0” on the Mac and the tech is pretty impressive; I am looking forward to exploring the Big Sur version of it.
The biggest problem they have right now is that subtle but important behaviors are being lost in the SwiftUI versions of controls, and they need to add them back. You start to notice how maybe keyboard focus isn’t quite the same, certain key bindings don’t work, tooltips aren’t present, etc. and it adds up. It is really quite easy to get something working in SwiftUI right now but it is really hard to polish it to the standards that Macs used to have.
The amount of compiler magic used by SwiftUI is staggering. By itself it's not a deal breaker, but closed source makes it almost impossible to understand what is going on.
This is one of the main reasons I have migrated to Rust for most new projects to be honest. I've been a big fan of Swift for years in terms of the balance it strikes between expressiveness and safety/correctness. But the way that function builders and property wrappers were somewhat hamfistedly jammed into the language to support SwiftUI has been a big turnoff. Previous iterations seemed like they had a very clear intentionality and priority around preserving the clarity of the language, but I'm less confident about the direction the language is currently taking in that respect.
Also the relative fragility of large swift projects with multiple dependencies has been a recurring frustration. It's been refreshing to work with Cargo, and not have to worry about doing surgery on a project every time a language update is released.
AFAIU all the magic used by SwiftUI is included in the open source compiler. AKA one should be able to reimplement SwiftUI on top of the OSS Swift language. Granted though, these features are not developed in the open.
Swift had to interop with objective-c right from the start, which itself had to interop with C.
SwiftUI feels like a wrapper over UIKit (or at the minimum CoreFoundation).
All in all, it seems impossible that so many layers of compromise over so many years, can lead to anything clean in the long run.
SwiftUI provides a completely new UI programming paradigm using the reactive model popularized by web frameworks, RxSwift, etc.
Using UIKit is just Apple current implementation strategy right now. That doesn’t comprise the SwiftUI model & semantics in any meaningful way. It doesn’t feel at all like a wrapper over UIKit IMO. It’s a completely new beast...
Love the ability to remove AnyView, that was a really confusing one for me the first time I saw it.
I'm really impressed by SwiftUI, it seems like Apple took a couple hundred really good UI engineers and threw them at this. Coming from a web background it's really refreshing to have these APIs. Swift as a language is part of it, changes to JavaScript like those mentioned in this article would be hard to come by (for good reason!)
Honestly, I think Swift UI's mess of syntax really makes the case for lisp. Four different function calling syntaxes? Trailing function calls? Jesus Christ.
On the other hand, it doesn’t quite feel ready. SwiftUI seems to be missing enough components that I end up needing to know how to use the existing AppKit stuff with autolayout, or know how things work under the hood to debug SwiftUI oddities. On top of that, there are few resources out there for learning macOS dev specifically — tons of stuff for iOS, which sorta translates, but not perfectly. I’ve been learning from the Hacking with macOS book, which is very good, and plenty of trial and error.
The other ding against SwiftUI for Mac dev seems to be that it’s only supported in Catalina, and it seems an awful lot of Mac users have held back from updating, so the user base might be diminished.
Most of these seem like temporary problems, but as a newcomer to this world it’s hard to tell if it’s too early to commit to SwiftUI.