Apple's use of Swift and SwiftUI in iOS 17
blog.timac.org
blog.timac.org
Here's the result:
https://lite.datasette.io/?sql=https://gist.github.com/simon...
You can use this to answer questions like which binaries are new in iOS 17 compared to iOS 16:
https://lite.datasette.io/?sql=https://gist.github.com/simon...
Or here's just the binaries in the /System/Library/VideoDecoders folder - it's interesting to compare iOS 1 (just H264H1 and MP4VH1) to iOS 17 (AppleProResHWDecoder, AppleProResSWDecoder, AV1SW, AVD, H264H8, JPEGH1, MP4VH8, VCH263, VCPMP4V) https://lite.datasette.io/?sql=https://gist.github.com/simon...
Details on how I built this here: https://gist.github.com/simonw/0b8a2ddaeab76fe407b08a2b20412...
I am a bit surprised to see Objective-C still dominating. It goes to show that transitioning languages is extremely difficult, even when you are applying the impetus to yourself. Consider the Python 3 transition in this light. Python 3 came in 2008 and I don't think it could be said the transition completed prior to 2020, so 12 years conservatively. Swift picks up in iOS 10 at 1%. So, perhaps one could estimate by iOS 22 some large majority of Swift in Apple codebases? And then maybe by iOS 30 Objective-C is down to 5% or les?
There is no reason to replace perfectly working code that is battle tested if the requirements don't change.
The fact that the new binaries on it are written in Swift is showing their 100% commitment to Swift, which is great to see. And why wouldn't you, Swift is a joy to work with, especially if you're from Apple :)
It fits in line with how I've seen Apple developers at conferences highlighting the memory safety aspects of Swift. They are maybe hoping to position it as a competitor to Rust on that front. I wonder how they feel Objective-C compares from a safety perspective compared to Swift. I wonder if that might influence decisions on what kind of stuff gets re-written in Swift.
I hope we can see further graphs like this to track what happens. I don't feel MS ever committed to C# in this way but that is due to ignorance at the numbers. I would love to see all of that data for Windows and even macOS.
Perhaps it’s just not increasing much since the value is in percentage and overall code size has increased dramatically.
I doubt they will rewrite Mach/XNU, for example, in the foreseeable future.
I think that’s impossible, Swift should try to be a great language for building Mac/iOS apps and hopefully frameworks.
But what do I know. I wouldn’t think writing a new industry grade C++ compiler in a modular architecture would be feasible. Just use GCC. And yet here we are with clang and LLVM.
There will be language subsets for embedded and kernel development, not all features would be able to be used at the lower levels.
There are reasons to rewrite it, though I’m sure it will take a long time and they’re prioritizing risk vs reward.
There are kinds of bugs that Swift can provably catch that Objective-C can’t.
There are bits of safety that Swift can ensure without needing to do additional boundary checks or something else, leading to faster/smaller code.
Perhaps biggest of all Swift doesn’t need a runtime like Obj-C. Apple has done an amazing job tuning it, but a direct function call is always going to be faster than message passing.
1. The empirical evidence does not support the notion of fewer bugs, even for static typing, never mind Swift
And no, this is not from lack of trying. People have tried to show this time and time again. And time and time again they end up not showing it, with effect sizes tiny and pointing in both directions.
And as an anecdotal example: which way has Apple software quality gone since they started adopting Swift and SwiftUI? System Settings anyone?
2. Swift is slow, not fast
I did fairly extensive research for on this for chapter 9 of my macOS/iOS Performance book. Even those cases where I fully expected Swift to be faster, which were not numerous, it managed to be slower. And there are really egregiously bad examples, like Swift Coding, which despite the overwhelming evidence to the contrary some people still believe to be fast.
Why do they believe it to be fast? Because so much work can be done in the compiler. So it must be fast. But it just is not. In fact, it's ludicrously slow. This is probably lesson #1 from performance optimisation: things are not fast because simply you did something that you believe to be fast. You need to measure to figure out whether they are fast and in order to figure out how to make them fast.
(And those mistaken beliefs actually lead to slow code, because you already did the thing that makes it fast, not need to check or optimise. I am pretty confident that a similar effect happens with static typing and safety.)
Or check out the computer languages shootout. Swift tends to be somewhat on par with Java. Which is not particularly fast.
3. Swift needs loads of runtime
For example, due to the somewhat bizarre idea of having protocols be polymorphic over (pass-by-value) structs and (pass-by-reference) objects, Swift has to dynamically dispatch the copying of individual arguments to a function when protocols are involved. If you're both lucky and not using modular code, the compiler may be able to figure out how to elide that dispatch. But it won't tell you if it managed to figure it out or not.
Oh, and speaking from 30+ years of experience: message passing simply is not the bottleneck in 99%+ of the cases, and if it is it is fairly trivial to remove.
https://www.amazon.com/gp/product/0321842847/ref=as_li_tl?ie...
The Codable stuff was this:
https://blog.metaobject.com/2020/04/somewhat-less-lethargic-...
As shown and discussed in the series, @objc is not an issue. Do you have reason to believe that Swift performance in general or Codable in particular have improved since?
I mean, you can run these sorts of tests yourself, and you probably should. It's not that hard.
Is your book available on Apple Books or some other electronic format besides kindle?
Swift most certainly has a runtime: https://github.com/apple/swift/tree/main/stdlib/public/runti... And most or all of it is written in C++, not Swift last I checked. Whenever you see a `_swift_fooBarBaz` symbol in a stack trace, that's the runtime.
Working code has also squashed a huge number of past bugs though.
Are you familiar with Apple's MO? Take a perfectly good, working app and replace it with a total rewrite with half the features.
On the consumer side, iMovie was probably the worst, not even being able to read projects made in the prior version. Not just the interface but the whole paradigm was different, only supporting a few features of the original program. I gave up on it.
iPhotos was another example: it had languished, but what came out had less functionality (no more external streams, for example) and simply threw info away (tags, face recognition, added metadata like location was all gone). Links to external tools were no longer available, though added later.
This happened to Pages and Numbers (& Keynote?) as well but I don't know if they count as consumer or pro apps. Consumer I guess.
On the Pro Side, replacing Final Cut Pro with Final Cut X (~2010 or 2011) pretty much drive video production off the Apple platform onto Windows. Like the iMovie case (I guess they didn't learn) it was a completely new interface without most of the features of the old version. I hear a lot of the functionality made it back in over the following decade, but you wonder why.
I think the loss of the pro production side in video (and replacement by Adobe) led to the abandonment of Aperture too. Apple announced that the consumer product Apple Photos was supposed to be the replacement -- what a joke!
But now, the Apple brand has its own status, independently of any particular group. Their products have gone the same way.
There are lots of those apps where they enhanced the generic user's ease of use, while maybe not maintaining features that weren't used.
I wouldn't be surprised if their apps are instrumented to work out what features are needed or used.
Their apps are now effectively cross platform across all of the devices you have, so they have focused on making that more seamless, while, of course, trying to hook you into Apple One to get the shared storage you need in iCloud.
It seems to me that Apple's strongly insular instincts serve them well for integrated product design, but for the Swift language, alas, they form a severe hindrance to wider adoption.
What more do you want?
Unfortunately it seems like they didn't really mean it.
It appears to be 50:50 with Obj-C for now. See how the Obj-C line in the "Evolution of the programming languages" chart is still growing steadily. I can see Swift taking the majority of new code for the next year though.
My take is that C has probably remained steady — all the new binaries in iOS are made up from the other three.
For C++ the amount has been growing steadily with every release, but it went from 14% in iPhone OS 1 to 12% in iOS 17.
Note that most of this change is between iOS 1-9, where Objective-C rose from 34% to 70% (+36) and C declined from 52% to 14% (-38).
By my rough count [0], the number of strictly Objective-C binaries increased by exactly 4 between iOS 16 and 17. The number of strictly Swift binaries increased by 9 [1], and the vast majority of binaries added use both languages. It's not clear from the data if there are substantial amounts of ObjC code in these binaries or if there are just one or two functions in each.
EDIT: The percentage tallies are calculated weirdly too—because they double- and triple-counted binaries that have multiple languages, they calculated all the percentages out of a total of 8723 binaries (for iOS 17) even though there are only 6030 in their data set. The correct percentages should be:
SwiftUI: 6%
Swift: 25%
C: 7%
C++: 17%
Objective-C: 89%
This is less satisfying because it doesn't add up to 100%, but the metric they used doesn't have any useful meaning.
[0] Using the following regex on the raw data files: / \|Objective-C\n/ [0] Using the following regex on the raw data files: / \|Swift(\|SwiftUI)?\n/ and
Take this all with a grain of salt as a lot of C++ code is really just C-With Classes. As well if i remember correctly you can wrap objective-C in C++ or vice versa.
"Consider the Python 3 transition in this light. Python 3 came in 2008 and I don't think it could be said the transition completed prior to 2020"
To be fair, yes Python3 came out but there were still a lot of Python2 libraries that had to be migrated to 3, so for most people it didn't make sense to use 3 when it came out.
Prior to some Swift version — Swift 4? don't remember — iOS apps that used Swift did have to bring their own runtime, and iirc this was because Swift was evolving so fast that Apple wasn't willing or able to commit to including a bunch with iOS.
Not just that - they wanted to have language features for stability and migration which they hadn't fully flushed out yet and implemented.
Now, Swift is part of the OS itself - which has good and bad sides, because policies to support older versions of iOS also mean you can't fully leverage all the new language features.
Its UI becomes desynchronized and self-inconsistent in ways I wouldn’t have believed are possible. The very fact that it exists and is capable of presenting as incoherent UI as it does is damning evidence against whatever UI framework it uses.
However, its predecessor UIKit is mostly imperative and it takes a lot of manual code to keep the UI reflective of the underlying data model. For this reason I find many IOS apps, and especially apple’s own, to be always mildly broken.
Programming in UIKit is like programming in JQuery, or maybe Backbone at best.
SwiftUI brings us to the modern age of react (but with less capabilities and more bugs)
IOS developers though tend to be pretty resistant to such “modern” paradigms. If you read the rest of the discussion on this post, you fill find that even using Swift, let alone SwiftUI is still a very debated issue.
Maybe the grass is greener, but I don’t find the same resistance for new ideas in the web (typescript) or Android (kotlin) communities.
I do wonder if this resistance is combing from an objective evaluation of the new tech, or the lack of desire/time to learn something new.
The newness is an issue because new SwiftUI revisions ship with new iOS releases, which means that big chunks of it are gated by the oldest iOS version you support. Jetpack Compose on Android gets this more right since it’s independent of the OS, but suffers from other tradeoffs (Java ecosystem and the rest of Android dev gives me a headache sometimes).
SwiftUI is also just missing various things that are present in UIKit, and so if you’re using those things it’s easier to write the whole app in UIKit instead of bridging those controls to SwiftUI.
I absolutely foresee going SwiftUI exclusive but realistically that’s still a few years down the road.
The framework lacking consideration for navigation until recently shows that its rollout has been half-baked, though.
At the start SwiftUI was something you could add to an existing UI/AppKit project, so individual parts could be rewritten. They've been building on top of that since. Refining the api and slowly letting you write more and more with just SwiftUI
This problem isn’t exclusive to SwiftUI though, WinUI/Windows App SDK is also mobile-flavored likely due to its UWP heritage, lacking basic desktop widgets like a tableview/datagrid.
Hah, it's far worse than that - Microsoft has let their desktop DX story stagnate for 15 years now (WPF was launched in 2006), since then Microsoft hasn't launched any new desktop-first UI framework for Windows, nor offered more than token improvements to User32, CommonControls, and WinForms since then.
It's no lie that everything MS has done in the UI-framework space since Windows 7 in 2009 has been a waste of time and money. It started-off with the "Metro" Windows Phone reboot, then the shoehorning of that into Windows 8, and the various XAML-derived frameworks since then - and none of them have attempted to tackle the very fundamental flaws (declarative data-binding doesn't scale, INotifyPropertyChanged breaks causality tracking and cannot be unit-tested, mutable ViewModels were carved by Lucifer himself!) - and as you said, no care or attention is paid to applications needing high information-density display.
----
...so while all this is going on, the Office org came up with its own in-house GPU-accelerated UI introduced in Office 2013 which we can all agree is slow, bloated, glitchy (y'ever used Excel with a 500Hz mouse?), but also proprietary and undocumented, so the wider Windows ecosystem can't benefit from the Office org's framework which would have otherwise (almost) neatly filled the gaps left-behind by the Windows org.
I just want Satya to hire me for the job-title of "VP of Consistent User-Experience" and I'd make it a top-priority that Windows itself comes with a reusable spreadsheet+datagrid component that all applications can use - and it wouldn't cost the company more than a year and a few million dollars - but save billions by avoiding lost developer confidence - and would serve to remind everyone that native desktop UX can always be better than browser-based UX.
---
Sorry, am ranting.
That's funny, just a few hours ago I was looking at some pics of Office 95 running on Windows 95 and reminiscing about how Office's menu bars and toolbars looked/worked differently than the system standard ones despite both being presumably worked on in parallel. Some things never changed.
You may be thinking of Office 97, which introduced the "flat" look for the toolbars and the animated sliding menus.
It is all about financialization of software so art and craft wouldn't matter. End goal is simply cloud desktop with integrated AI/ChatGPT user interface which can be charged per user / per month basis.
We ended up building a cross-platform desktop app in Qt and QML, and it works great.
You are going to have to be willing to stick your neck out a bit though, that’s true.
I suspect even though it was always meant to be a cross-platform UI framework, the initial layout system was designed more toward composing and filling a smaller fixed space than for dealing with large resizable windows.
There’s a ton of potential there and I’m looking forward to having sufficient APIs and documentation to work efficiently with it. At this point it’s kind of painful for a hobbyist like me.
What’s not that hard is managing a bit of state and writing sensible CSS to make it reusable.
as the apps get big, state becomes a mess, fully reusing code is very hard, making anything even slightly reactive becomes not only a lot of code, but a jumbled mess of mutability, usually copy pasted from somewhere else. I will take any other type of app over that - I don't care if it's angular, vue, react, next, whatever.
So i contend that not only is "managing a bit of state and writing sensible CSS to make it reusable" very hard, I haven't even seen it done ever, at least in my personal experience of the code I touched
At a much much smaller scale however, jQuery and CSS or in many cases just HTML and CSS will do just fine. Knowing which approach to take is the mark of someone with some level of experience above junior.
Instead they burn an insane amount of energy (and unfathomable bandwidth) inventing, learning and debugging crazy abstractions and build systems (that change every year or so) on top of the native platform that is the web.
It really feels like a collective bad trip that I hope the industry wakes up from, eventually. But after more than a decade of this insanity, I’m not holding my breath.
Sometimes you choose hypothetically difficult debugging if it eliminates the need to deal with the mechanics of the lowest level of interacting with a system. If you haven't needed to do that, then you'd be inclined to think it's an unlikely situation to be in.
Thanks, I vomited a bit into my mouth.
Resistance to SwiftUI has more to do with the incompleteness and bugginess of the framework than a refusal to embrace modern paradigms.
A common impression of SwiftUI is that it makes hard things easy and easy things hard.
Besides that, many of the “Awards” views frequently show incorrect/ancient/impossible data. For instance I recently saw “You will earn this when you reach you move goal 100 times. You’ve reached your move goal 102 times so far.” with the seat not unlocked. The number sounds only slightly off, but keep in mind that’s 3 days of stale data. I saw similar bugs with the “Perfect Week” award and “Longest Move Steak” one. (At one point I had a move streak of 21 days, the badge said it was 14 days, and the perfect week badge was still not unlocked. You’ll note any 14 day period must contain a full monday-sunday period, not to mention in reality my streak was 3 weeks).
The daily summary view is admittedly fine. Though the refresh interval is something like 15 minutes which is absurd for a pedometer. Not sure if the app or the API is to blame there.
Sight aside, but not really. The settings/Account modal is impossible to discover, and when you do 5/6 menu options have a reasonable flow where you can click to go into the detail view, then hit back to return to the main modal (or exit entirely). Except for the “Change Move Goal” detail, which can only be exited entirely, it is impossible to return to the Account modal directly.
I’ve never used “Fitness+”, their paid offering, but I assume the quality there would be about as bad as everywhere else.
My weekly and monthly sleep averages look about right. The 6 month average is off by about 1.5 hours.
Funnily enough, it’s been off by that amount consistently for at least half a year now.
Preferences is such a mess. Many apps are simple backports of touch-only apps.
I don't think Apple requires all developers to have read the HIG.
vpn -> The menu makes NO difference in all options in the search results.
performance -> on an M1, it takes about a second to switch each pane.
Looking for a way to change the background image on your desktop? Better remember to type wallpaper.
"Introducing a Memory-Safe Successor Language in Large C++ Code Bases"
https://www.youtube.com/watch?v=lgivCGdmFrw
"Swift as C++ Successor in FoundationDB"
My impression is that it is useful only in the Apple ecosystem. It that correct? Is it worth learning for things other than iOS and macOS applications?
I relished the day Swift was announced, and have been using it ever since.
Headers are a feature, not a bug. They're the API. They help document the API and also keep it separate from the implementation.
Xcode presents the equivalent of a “header” when you follow a symbol to a framework you don’t have the source for… it’s a swift file full of definitions only and no implementations. The compiler emits this for you automatically as a .swiftinterface file
> or keep things non-`public`
I definitely am a swift developer that would complain about this. It’s way too easy to be cavalier about using the “public” keyword and making things part of the public API when they probably shouldn’t be. It’s like engineers have muscle memory from Java and just type “public class” without really questioning why first.
It's so incredibly slow, though, which is frustrating. It would be ok if only this were as instantaneous as checking a header file.
Ironically, almost everything about "Swift" is slower than Objective-C.
That problem was already solved with header files; trivial to split interface from implementation, they’re just two different files. But sometime around the 90s, probably Java and this was deemed inconvenient. Now we’re trying to reinvent that same pattern
Headers are such an idiotic design, over-abstraction harms locality of reasoning.
Why parse out a whole C file when you can get the only bits that matter for compiling your file from a 30 line header?
This is a good pattern for some cases, like the public members of a package. However, I love that I don’t need to do this for every class I write.
And if you do use this approach, at least swift will emit a compile error if your protocol and implementation signatures don’t match.
ObjC will happily compile if your header is missing an implementation and crash at runtime.
Once I had all the convenience guts in place, writing actual functionality has been a delight though (outside of the overly-verbose let/guard and type casting)
That said, I'm pretty sure I'm also probably just hard headed and doing it wrong, and could've learned the accepted patterns/methodologies lol
My other complaint with it compared to Swift is how one needs to pull in a bunch of utility libraries to do many things that come stock with Swift.
Possibly in ways that are very inconvenient/hard to use in Obj-C.
Objective-C does just about everything it can to make sure you can mess with it at runtime and confuse the ever living hell out of any type checker that wants to be strict.
And the additional strictness is one of my favorite parts of Swift.
Of course, C has a lot of ugly traps which makes it less than ideal for this domain. This hypothetical subset language addresses those issues. While, again, you would only reach for the 'Objective' parts when your code benefits from being object oriented.
It is true that the inherit dynamism of message passing makes static analysis impossible to cover all cases, but as with all things in life there are tradeoffs. You lose the nice aspects of object oriented systems if you do not allow for that, and OO is particularly well suited to UI code.
Of course, Swift abandoned the object oriented model completely. Which is fine. But Objective-C showed that you can have your cake an eat it too, offering OO where appropriate, and a non-OO language for everything else.
Objective-C's downfall was really just in that C didn't age well – which, among other things, I am sure contributed to seeing the use of the 'Objective' bits where they weren't really appropriate.
Classes, interfaces,interface and class inheritance, polyphormism, variance, type extensions, compile time and dynamic dispatch, overloading, associated types.
Is there some value in this logically flawed correspondence that I have overlooked? What is it trying to add?
Where both languages are poor is how large the binaries they produce are.
But seriously though, CLOS and Smalltalk-style OOP is probably the only flavor of OOP I really enjoy to use, and Objective-C gets you way closer to that than C++ and Java do. (e.g. the way KVO is implemented relies on "isa-swizzling", or dynamically changing classes at runtime)
The only app I'm currently maintaining and proud of[1] makes tons of use of "traditional" OOP. It uses lambdas and FP when necessary. I think it makes absolutely no use of JavaScript's dynamic features. I'm fairly sure this code would port easily to ObjC.
After 15-20 years, you just get bored of doing things in novel or "pure" ways, and do the bare minimum needed to get the job done that's in front of you.
Maybe saying "flavor of OOP" was too vague, but I am talking about implementations of object systems, not the (ill-defined) notion of OOP.
Using your analogy with hammers and screwdrivers, my post is less "I prefer screwdrivers over hammers" and more "I prefer screwdrivers with bit holders over screwdrivers without bit holders"
Even JavaEE was initially born as a Objective-C framework, Distributed Objects Everywhere.
It’s less verbose (even if I’m not a square bracket hater. It has some really nice new abilities like async (way easier/cleaner than callbacks in many situations) and now actors.
But honestly 90% of it is true type safety. The type system is so much more powerful and expressive compared to Obj-C.
There is only one downside, and it’s real. Compiling Obj-C was instantaneous. Swift is MUCH slower, which also slows down error messages and hints. And the fancy type stuff can even timeout the compiler.
Combined with some Xcode issues (stale info anybody?) and it can be a pain.
But I’m happy we have Swift.
> Again please note that a single binary can be counted multiple times, so the sum of the binaries in this graph is greater than the total number of binaries
So even if a binary only uses a small shim of Objective-C, it'll still count towards the Objective-C number.
You can still call new Swift only APIs from Obj-C, but you’ll have to write your own glue layer.
Now you've got two things to get out of your mind.
[1] https://arstechnica.com/gadgets/2021/04/google-is-now-writin...
[2] https://security.googleblog.com/2023/10/bare-metal-rust-in-a...
What does this mean (what is app lifecycle)?
It gets worse when they get to the percentages: they list 61% as Objective-C's number for iOS 17, but 61% of what? According to the raw data, Objective-C is used in 88% of all binaries on iOS 17, with Swift used in 25% (instead of the 17% they list). Their calculated numbers are derived from a denominator of 8723 binaries, even though they only have 6030 in their data set, because they wanted the numbers to add up to 100%. That makes a nice chart, but it has no meaningful interpretation.
The reason why it looks like Objective-C is losing ground is that every Objective-C+Swift+SwiftUI binary increments the denominator by 3 instead of by 1, and there are more of those added every single year. Since each of those binaries only adds 1 to the numerator, Objective-C's share of the binary pie seems to be decreasing even though it's actually keeping up with Swift.
It's entirely possible and even likely that Swift is increasing faster than Objective-C in terms of lines of code, but this data can't be used to show that.
Edit: I see much interaction with this comment, but no response.
In macOS 13, the system settings was rewritten to use SwiftUI instead of UIKit. I had a 2019 Intel MBP. Before the rewrite, it was super swift (sorry). After the rewrite it took almost a second to go from section to section.
Now I'm on an M2 machine so it's fast again. Congrats Apple.
LOL have you used Xcode lately? It's painfully slow, and getting worse.
Apple engineers use all of the same crappy Apple software that we all do. The problem is that Apple executives have decided they don't care and are unwilling to invest the time and resources in performance optimization or good design. The relentless yearly update cycle will continue until morale improves. Steve Jobs is gone not only physically but also in spirit. It's Tim Apple now.
Honestly though, the problem with XCode for me is 90% that the autocomplete is just enormously stupid (they need to just ask JetBrains how to do it), and that Swift compilation is slow (which they are working on).
I do remember.
> XCodes enshittification was well on its way.
It's Xcode, not XCode.
Anyway, Jobs took a 6 month leave of absence starting January 2009, during which he got a liver transplant, and another leave of absence starting January 2011, after which he finally resigned.
Xcode 4 was released in March 2011, although it had been in development for some time before that. I wouldn't really say that its "enshittification" was "well on its way."
That's... insane. Even worse, the graph appears to show a superlinear trend. For comparison, iOS 2 had only 278 binaries.
With such out-of-control software bloat, secure computing is never going to happen. There isn't enough brainpower on the entire planet to secure a system that grows to the tune of hundreds of components per year.