Honest question. Not trying to troll. One of the pitches in the earlier days was “C/Objective-C OK, but you can’t write safe/next level code with it—-Swift will close that gap.”
N years later, it doesn’t feel like there has been a step change in Apple software quality; if anything Apple software feels less solid, and looks cool “look what I did” extension points. I mean, some of the tings you could do with runtime categories, and runtime prototypes were really cool. Now when I work on my 2 apps that originally happily port to Swift/UIKit, I’m just left confused with how to make things work. I’m happy when it finally works, and don’t ever try to improve the thing, it’s too much work.
There’s lots of different variables at play here; I’m not trying to stretch inference too much. Heck, it could have been that with adding Swift to the mix, the forces that have contributed to reduced quality in Apples stuff would be even worse.
I’m just frustrated. When I work in Elixir, I’m like this is cool. When I work in Kotlin, I don’t feel like “Apples got a language like this too, but it’s got that extra special zing that used to make stuff Apple touched cool.”
I feel the same. Apple software quality certainly hasn’t increased. Years back I remember some apps crashing suddenly after updating MacOS. I checked the binary and saw they’d started adding Swift.
Half a decade later it seems like it should be better and Swift stuff should be stabilized. But nope, I’ve had more little glitches in both iOS and MacOS. It’s hard to say it’s due to Swift, and not management priorities. Still it feels partially related to Swift.
Swift’s goals are great, I like the syntax, but the language implementation seems to just special case everything rather than having coherent language design.
That and Swift de-emphasizes Obj-C message passing. I have a pet theory that message passing produces more robust GUI software that’s easier to adapt to complex needs.
It is not just the language but the frameworks. SwiftUI is a wreck, and still not mature even after 6-7+ years in 'production'. You still have to drop to UIKit to do advanced UI, and for what it is, SwiftUI is just not practical enough for cases that are not trivial. The trouble is that all new kids/engineer are learning it first, which means software wont get better. Apple need to improve it first, and I don't see advanced folks ditching UIKit anytime soon for advanced UI.
Seems like another case of the general trend in software development of easy things becoming easier and hard things becoming harder.
I don't completely agree with you. Having used both SwiftUI and UIKit extensively, I value both of them and think they are both quite strong in different areas
I have published a word game written entirely in SwiftUI [1], the effects and animations would have been much more difficult to do in UIKit, and the app itself would have been hairier to write and maintain [2]. I also track crashes, and this particular app has had four crashes in the past year, so I am very pleased with the stability
That said, there are definitely times, as you say, where you have to drop to UIKit. For the word game mentioned above, I had to drop down to UIKit to observe low-level keyboard events in order to support hardware keyboard input without explicitly using a control that accepts text input
SwiftUI is mature, it's pretty advanced — especially for graphics and animation heavy UI. It has limitations, particularly around advanced input event handling, as well as the application/scene lifecycle
I plan to continue to use both UIKit and SwiftUI where they make sense. It's easy enough to bridge between them with UIHostingController and UIViewRepresentable
[1] https://retrogram.app
[2] Specific examples include: image and alpha masking is trivial in SwiftUI, Metal Shaders can be applied with a one-line modifier, gradients are easy and automatic, SwiftUI's Timeline+Canvas is very performant and more powerful than custom drawing with UIKit. Creating glows, textured text and images, blurs and geometry-based transitions is much easier in SwiftUI
What baffles me the most is testability of SwiftUI. It simply does not exist.
This is true, I wonder what Apple uses internally to test SwiftUI.
That’s a shame!
I haven’t used Swift UI in a couple of years, but I always thought the basics of it were excellent.
They got the declarative API foundations right I thought.
Shame it’s still flakey.
The preview used to crash constantly last time I used it.
I have a good bug right now. My wife bought a Macbook Air. I use High DPI and she does not. It is impossible to switch between users in this situation, one of the core functionalities of the computer is just broken. Makes me wonder if anyone at Apple uses these computers..
No one tests multi-user functionality, afaict.
It’s insanely buggy. My wife has two user accounts, one for her work and one for everything else, so she can switch out of the work user at the end of the day to put it out of her mind.
She comes across bugs on the regular that I’ve never seen in 16 years of Mac use, but only when the other user account is logged in (i.e. quick user switching rather than a full log out).
Stuff that user accounts shouldn’t even make any difference to, like the menu bar disappearing or rendering too far up so it’s half off screen. Save dialogs stop appearing. Windows that are open but appear to be rendering off screen somewhere. It’s wild. This is on a < 1 year old MacBook Air running the latest OS. It’s an absolute shambles.
His has been my experience as well. The changes from System Preferences to Settings have been an abomination. Previously we had uniquely designed layouts for each setting. Now everything is a list. Now menus scroll without any indication that there’s more content. “Sheets” are no longer resizable and take up the center of the view. User space networking (cool) hangs while pegging one CPU (lame). Everything requires special permissions and several times a month I’m having to figure out why a program can’t access something. Writing programs forces using Swift UI APIs that don’t have equivalent functionality to their App Kit versions.
After over 20 years, I’m really unhappy with macOS. The last five years have have been a huge productivity regression.
I created a new user on my macbook for my girlfriend when her laptop broke, and she could see my files in the “Recent files” tab. I’m not even sure if there was a separation of files. And I have no clue what the intended boundary is supposed to be between users.
I made a new user for Zoom screen share and was equally confused when my personal files and info would show up in searches and such. And it seems like most things install globally?
Ended up using a whole new computer to have a clean screenshare environment.
Has Apple been testing anything in the last many years?
How much they can get away with.
Lmao!! Thank you for that laugh.
That doesn’t mean much. Swift is new. Usable Swift even more so. All of the apps Apple propose have legacy. New apps from now (e.g. Invites) will be much more interesting.
> Swift’s goals are great, I like the syntax, but the language implementation seems to just special case everything rather than having coherent language design.
This could not be furthest for the truth. The entire process of proposing a new language feature to getting it implemented and shipped is out in the open for everyone to participate/see.
https://github.com/swiftlang/swift-evolution
What’s that got to do with coherent language design? Just because it’s somewhat open doesn’t mean it has consistent design. Then by all accounts Apple just forced through language changes needed for SwiftUI.
I agree that that is the one counter example for the above. Apple forcing the closure syntax to better cater to SwiftUI left a sour taste in the mouths of an entire community.
Too many cooks!
And no Steve Jobs to pull them down to earth.
Steve Jobs, of course, was always involved in the details of programming languages targeting his platform.
He would probably raise hell about the state of the new macOS Setting window though. How this thing made it through QA remains a mystery.
He really was involved. As I understand it Obj-C was championed by him. NextSTEP was largely software related:
https://youtu.be/Hu-jvAWTZ9o?si=PalSP6POofiRuj3a
I still feel like GUI programming hasn’t progressed in the years since this. Actually they’ve regressed in many ways.
I wasn't there so I can't say for sure.
But my impression watching from the outside is that he had a finger in every pie.
Conversely, Dart does the exact same thing and is probably the best designed language I’ve ever come across
Best designed? Really? Support for something as basic as consistent integer types across platforms is non-existent.
Software written in a simpler language like Objective-C - verbose, fast to grok and fast to compile is actually more maintainable in the long run than a so-called "developer friendly", humongous, complex and slow-compilation language like Swift.
A lean language reduces the surface area for beautiful expressiveness by clever people - making sure the dumb/junior guy who is maintaining your project in the future can actually fully understand what is written. And it can build and run fast - so you can iterate and test out software behaviors fast.
No one in this world is immortal. If it takes too much time to grok code, write/compile/run tests - a developer will be disincentivized to do so, no matter how amazing the language features are.
My guess is that Swift has adversely affected Apple's overall software quality. As more software moved from Objective-C to Swift, quality has dropped precipitously.
It's easier to read and navigate a well-written Swift codebase than a well-written Objective-C codebase
Conversely, it's easier to debug an Objective-C app than a Swift app, simply because compiling and debugging is so much faster, and debugging so much more reliable
I don't know about a software quality drop being attributable to the migration to Swift. So many other things have also happened in that time — much more software that Apple produces is heavily reliant on network services, which they are not very good at. I find Apple's local-first software to be excellent (Final Cut Pro X, Logic, Keynote) and their network-first software is hit-or-miss
They have also saddled developers with a ton of APIs for working with their online services. Try to write correct and resilient application code that deals with files in iCloud? It's harder than it was to write an application that dealt with only local files a decade ago!
Swift is easy to blame, but I don't think it's responsible for poor software. Complexity is responsible for poor software, and we have so much more of that now days
There's a limit to how "lean" a safe, low-level language can be. Rust is leaner and simpler than Swift but not by much, and pretty much all of its outward features are "load bearing" to a far greater extent than Swift's.
(People have tried to come up with simpler languages that still preserve safety and low-level power, like Austral - but that simplicity comes at the cost of existing intuition for most devs.)
As someone frequently flipping between Swift and Kotlin, while I don’t necessarily feel like Swift is massively superior, I often find myself thinking “why is this so quirky and pedantic” when writing Kotlin.
For example, I really really wish Kotlin would adopt Swift style if let/guard let statements. Kotlin smart casting doesn’t work just often enough to not be able to consistently rely on it and the foo?.let { } syntax is ugly.
Combined with the JVM warts of gradle and jankiness of code stripping and obfuscation, generally speaking if I could opt to use Swift in place of Kotlin for Android dev I would do so in a heartbeat.
Ha, I switch between the two as well, but I feel the opposite. Kotlin is much more intuitive for me, and Swift is more clunky. I do miss guard lets in Kotlin, but that’s about it.
Have you tried Skip Tools yet?
It’s a set of tools intended to do just that.
https://skip.tools/
Skip tools is pretty cool and I very may well use it for at some point, but it works by translating Swift+SwiftUI to Kotlin+Compose and I’d prefer a more direct approach that lets me build Android binaries with Swift (preferably with the whole of UIKit available, though that’s not likely).
From the FAQ…
> Skip supports both compiling Swift natively for Android, and transpiling Swift into Kotlin. Read about Skip’s modes in the documentation.
https://skip.tools/docs/faq/#modes
Yes, it transpiles a Swift+SwiftUI codebase into a Kotlin+Compose codebase. I don’t want that intermediary step, I want the Swift itself running on Android.
> Skip supports both native mode - in which your Swift is compiled natively for Android - and transpiled mode - in which your Swift is converted to Kotlin. The mode is specified at the level of a Swift module. Each mode has strengths and weaknesses, and it is common to use both native and transpiled modules within a single Swift-on-Android app.
https://skip.tools/docs/modes/
The ?.let syntax is terrible. I don’t see how anyone thinks it’s better than doing a normal if != null check.
Feels like a lot of people like making dealing with null as complicated as possible.
The only time I ever use it is when the if != null check doesn’t work (aforementioned smart cast failure) and I don’t feel like creating a local var to fix it.
I have been skeptical of Swift ever since I heard the original goal was the one language to rule them all from Assembly to Javascript. When something is too good to be true it probably is. But I have also given Apple plenty of benefits of doubt.
It seems Swift 6.2 is still unfinished and is acting more like Java. Eternal evolution of language. While it is popular among tech and HN crowds to have new language and framework to play around and work. It brings particular little if not negative user experience in terms of final products. I often wonder if Apple could just have some light touches of improvement on Objective-C in the past 10 - 12 years and instead focuses on actual OS and Apps quality.
It is this lack of focus that has been with Apple since Steve Jobs left.
> It seems Swift 6.2 is still unfinished and is acting more like Java. Eternal evolution of language. While it is popular among tech and HN crowds to have new language and framework to play around and work
You can have both. Rust feels "mature" and "finished" if you stick to the stable featureset, but it's still bringing compelling new features over time in spite of that. But this can only be achieved by carefully managing complexity and not letting it get out-of-hand with lots of ad-hoc special cases and tweaks.
Objective-C being stuck in the 1990s forever was not necessarily a good thing.
Stuck in what way? It would have been easy for Apple to make an "Objective-C without the C", where it's still using message passing and the Foundation libraries, but without header files, raw pointers, and all the @messy @syntax. Add little goodies like auto-stringification of enums and so on. I think that kind of superficial cleanup would have been enough to modernize the language. They could have spent the rest of all the time that Swift has consumed on better dev tooling.
I mean, "Objective C without the C" is just Smalltalk. It exists already. But that doesn't help you if you want any amount of backwards compatibility with the existing ObjC ecosystem. So you're kinda forced to go with the low-level approach.
What would stop Apple's hypothetical "Objective-C without the C" from talking to existing Objective-C code? After all, Swift can use UIKit just fine. Even mixing C++ and ObjC is reasonably easy.
In a sense, MacRuby was trying something similar, but the dependency on a GC doomed it.
Umm...Java is extremely conservative in adding new features. Not really sure you can compare to Swift that throws 10x the features in with every major release.
Also, if it hadn’t been (slowly) improving all this time then I would have defenestrated my work laptop, myself, or both long ago.
I’m trying to imagine using it without the stream API just shuts my entire brain down. Records arrived pretty recently and are already essential for me.
You will always have to pay me to program Java, but you’d have to pay me 5x my current salary to do it in Java 8 or earlier.
It's second system syndrome combined with the fact that Objective C and the NeXT underpinnings were put together by a team of truly the greatest minds of a generation.
Swift was put together by some great minds, and some minds, Apple still attracts talent, but in far lower density. This isn't even a jab, just from the fact that they are far larger and the talent pool is smaller with far more competition.
What percentage of genius level developers want to work for a company where they can't talk about their work and generally get zero public credit?
Good code is just one of many ingredients to great software, and programming language is a small factor in good code.
Swift was never going to make Apple software great (nor Go or Rust or anything else for anyone else).
Though, honestly, if you're thinking about computer languages in terms of cool, you're going in the wrong direction.
It’s easier to write more robust code with Swift, but if Apple don’t prioritise quality, the language can’t fix that.
Swift wasn't designed to solve any of the problems Apple engineers had writing customer-facing software. It was a shiny new language which could be marketed to third parties as something modern and familiar, unlike Objective-C with its odd mix of C and square brackets.
Surely developer productivity and maintainability have increased from the ObjC days, no? Swift criticisms aside, it certainly allows access to more ergonomic high-level coding patterns.
A big one that I feel is under appreciated is how Swift has rooted out nearly all passing around of untyped data, untyped dictionaries, casting without checking, etc in Apple platform projects.
I don’t mind Objective-C when I’m the one writing it and can ensure that the code is responsibly written, but it wasn’t unusual to have to work on existing Obj-C codebases littered with untyped data, casts, etc some amount of which was inevitably erroneous and only seemed to work correctly. Chasing down the origin points of data, fixing a laundry list of method selectors, and adding in checks always sucked with the compiler doing little to give you a hand. With Swift, even in codebases with poor hygiene fixing things is easier since the compiler will yell when something’s wrong.
Just curious, but would it have been feasible to update the Objective-C compiler to reduce these pain points?
Or was there issue more intrinsic to the design of the language itself?
With the caveat that I’m not all that knowledgeable about compilers, as I understand it, no not really. The compiler’s “reasoning” about types is extremely rudimentary and is easy to “deceive” because like a C compiler, it trusts that the dev knows what they’re doing. This can enable an experienced vet to move quickly due to low resistance, but makes the occasional slipups that even vets commit easy to miss.
You’d basically need to implement the Swift compiler in the Objective-C compiler to get similar type safety, but to make it work you would probably need to change various bits of syntax, drop inline intermixture of C and C++, and remove a lot of Obj-C’s dynamism, basically making it a new language. That’s why Swift was created, and in the past Obj-C’s bracketed smalltalk-like syntax had proven unpopular amongst newcoming devs, so they chose a more mainstream syntax instead.
Thanks for this! More or less what I expected, just wanted to be sure.
This might just be the long term effects of a platform dominated by people who generally value hardware over software.