Rendered at 21:59:46 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
rayiner 1 days ago [-]
The problem with complex systems is that you can be dead long before you realize you're dead. Things can continue to seem "pretty good" for a long time just from the inertia of past good decisions and built-up infrastructure. You see some fraying or cracks but everything looks fundamentally sound, until it isn't.
Apple's inability to deploy a new UI framework that's better than the previous one is troubling. This is the company that shifted from Toolbox to Carbon to Cocoa and each step was better than the last. Could Apple build MacOS X and Cocoa today if they didn't already exist? Microsoft's two decades of failure to ship a true successor to Win32 suggests that Microsoft (at least, the operating system side of the company) died a long time ago. I wonder if we'll say the same thing about Apple 10 years hence.
ksec 18 hours ago [-]
7 Years of release on Swift UI, 12 years for Swift.
This isn't 7 years of development, but 7 - 12 years after release. And to most these past 7 - 12 years are an ongoing beta development. It is unfinished, unpolished with no end in sight. And I have been extremely critical since the beginning.
But the problem runs much much deeper. It isn't the technology that is the problem, not the devs who are making it. It is the person making the decision as to WHY this was allowed from the get go. WHY this was allowed to be released, or even before all that WHY resources for development of these ideas were allowed in the first place.
For every yes that are a thousand no. Instead a lot of Apple's software development can be summarised as resume or KPI bonus driven development. It is not as bad as Google and Microsoft, but it is clear Apple have this problem a well.
If you look back into Jobs era of Apple software, ( and not just software ) Apple manage to have done most things 2x better with half the resources. The whole Apple now is bloated. And yet everyone is chanting Craig Federighi all the way.
And it is funny because for the vast majority of these 7-12 years I was the only few on HN and Twitter that was extremely skeptical of it, to the point I gave up writing ( or ranting ) about it before majority Swift and Swift UI developers negative sentiment emerged.
And I have often asked the same question every single time, what if they just spend one fifth of the resources to iterate and improve C / Objective-C and Cocoa. All the resources on Swift and everything adjacent to it could have been better spent somewhere else.
I have high hope for John Ternus, hopefully he gets his political game right and manage to change course for Apple software somewhere down the line.
rayiner 7 hours ago [-]
> Instead a lot of Apple's software development can be summarised as resume or KPI bonus driven development. It is not as bad as Google and Microsoft, but it is clear Apple have this problem a well.
When did the term “KPI” come into use at Apple? I’m aware it was used in management circles decades ago but I don’t remember it being so common say in 2005. The underlying concept is sound, but the problem with abstracting it under an acronym is that it treats KPIs as somewhat fungible regardless of importance. It’s like “lines of code” as a productivity measure all over again.
DarkNova6 10 hours ago [-]
I left Swift and SwiftUi behind be 5 years ago when I switched jobs. I had fond memories and always eyed going back.
What were the emerging problems that you talk about? I am actually curious because I was quite fond of the DevEx
ardit33 15 hours ago [-]
I agree with you. Swift should have been a modernized Objective-C. It should have kept the best parts of it, which made it a joy to use, and leave the archaic and the weird things behind.
it would have been a great language, meanwhile they decided to throw everything out and created a language that it is overcomplex, and it is failing to gain any traction outside iOS / Apple's ecosystem. Basically, if you weren't required to use it, nobody would, which makes it a failure.
SwiftUI, should have been a rendering template/library integrated with UIKit. Also, cleaning up some of the UIKit syntanx and framework (simplifying it), and use SwiftUI as a template for UI, would have been ideal.
SwiftUI instead was pitched as replacement, yet it is not near as capable as UIKit, and it is not feature parity even 7 years later.
Just bad leadership by Apple in this case. (probably many of these decissions were 'promo / resume padding driven' as it happens in many large companies).
ksec 15 hours ago [-]
While reading this comment, two of Steve Job's line pops up in my head. I think it was the Apple Park opening, and Steve response to insult in WWDC 199x.
> "We need to be true to ourselves, and remember what is important, that is what going to keep Apple Apple, is if we keep us, us."
> "You have got to start with the customers experience and work backwards to the technology.
Right now it feels a lot like Apple without Steve Jobs the first time round. On paper there are a lot of cool tech being worked on. But in the end it was tech from NeXT that really shines.
And a lot of these tech don't actually benefits the customers. If the choice was a language and framework that is slightly harder to developers but brings overall higher quality Apps because the barrier is higher. Compared to a language that wants to replace Assembly to Javascript while being easy to learn like Visual Basic and for everyone to code. I would much rather pick the former.
Edit: I suddenly remember I also submitted a Core Animation introduction video from Steve a while ago on HN [1]. 20 years later we have gone backwards on a lot of things.
I remember this video, from way back. Then, it was impressive, but it also felt logical that machines of that era were able to do it. So it wasn't magic. Just good engineering. Now everything is jank & stutter and my 64GB 25 times more powerful machine just refused to play back a YouTube video in my Safari tab since I have too many windows open.
rayiner 7 hours ago [-]
My iPhone 16 Pro is the jankiest user experience I’ve had on a new iPhone ever. On my Mac the settings app pauses and stutters. Jobs would have thrown things if he ever saw this.
MichaelZuo 8 hours ago [-]
My base 2019 macbook pro 15 on Mojave is actually faster than new macbook pros today on some tasks.
There’s no way Apple doesn’t know about that internally. So I don’t see any other explanation… other than a lack of care, or a bozo explosion.
simlevesque 7 hours ago [-]
Which tasks ? I don't believe your claims.
MichaelZuo 4 hours ago [-]
If you dont believe me… nobody is stopping you from testing various things on the same model?
And if you dont have it already… then what could I possibly say that would motivate you to buy a used one to do the testing to confirm?
Edit: And even on my ipad pro m2 doing literally nothing other than swiping to the app library often causes a visible stutter and lag for hundreds of miliseconds… so if you really think it’s flat out impossible to find consistently slower things on the much more complex macos… idk what to say.
simlevesque 2 hours ago [-]
Why should I need to do any testing ? I'm just going to keep on not believing you until you back up your claims.
And your iPad example doesn't make sense at all, you compared 2 Macbooks and now you're talking about another OS altogether.
> idk what to say.
You could just tell us one example of something that's faster on your 2019 Macbook Pro 15 versus a M5 Macbook pro and how to reproduce it.
meerita 5 hours ago [-]
I completely agree. Apple went from making “wow” products to “meh” products. Everything started to decline after Steve passed away.
saagarjha 11 hours ago [-]
> it would have been a great language, meanwhile they decided to throw everything out and created a language that it is overcomplex, and it is failing to gain any traction outside iOS / Apple's ecosystem. Basically, if you weren't required to use it, nobody would, which makes it a failure.
> Swift should have been a modernized Objective-C. It should have kept the best parts of it, which made it a joy to use, and leave the archaic and the weird things behind.
That's what Objective-Smalltalk is, or rather, what it started out as.
It has now gone further to actually implement Brad Cox's idea of a "Software IC", by taking on ideas from software architecture and metaobject protocols.
> SwiftUI, should have been a rendering template/library integrated with UIKit.
Do you mean it should have used some sort of XML-ish/HTML-ish templating mechanism? For Interscript, I keep looking at that approach, but so far haven't gone down that road (except for HTMXNative, but there it actually is HTML, so...).
dwaite 6 hours ago [-]
> and leave the archaic and the weird things behind.
The number one archiac/weird thing was message passing instead of methods. Number two was square brackets for message passing.
What would be left of Objective-C once these were left behind?
> and it is failing to gain any traction outside iOS / Apple's ecosystem.
Objective-C was on a path to gain serious traction outside of the Apple ecosystem?
pjmlp 8 hours ago [-]
So just like Objective-C?
Rescued by NeXT's acquisition, having failed to gain market adoption otherwise.
steve1977 1 days ago [-]
I think the problem with SwiftUI in a way was (or is) that Cocoa was so good. And, at least IMHO, it didn't need replacing, just improving.
But I feel like Apple wanted to appeal to young web devs and tried to offer something more similar to what these are used to.
monster_truck 1 days ago [-]
Totally agreed. I kind of figured things were going to get shitty when the guy who made autolayout got hounded on so hard that he left.
I sure hope they can figure out a way through. Whatever it is, SwiftUI isn't it.
rudedogg 1 days ago [-]
> Whatever it is, SwiftUI isn't it.
I think this opinion is heavily shared by Swift developers now, but the messaging every WWDC is always "Swift and SwiftUI is the best way to build apps for Apple Platforms", etc.. If you have to keep telling everyone what they don't believe is true, it's a sign there's a problem.
It feels like someone with a lot of organizational power is disconnected from the pulse of the community. SwiftUI is undeniably clean in a lot of ways, it presents beautifully and fits on slides well, but that matters less and less, and this all wasn't really working out even before LLMs disrupted things.
steve1977 1 days ago [-]
Well the problem now is Apple would need to admit they made a mistake. And Apple does not make mistakes.
mpweiher 14 hours ago [-]
Yes, they don't ever openly admit mistakes.
But they do quietly drop or fix them, covertly acknowledging they were mistakes. Often with this messaging: "we have this new shiny thing that is even better than the old shiny thing (that was really a turd)".
Remember "garbage collection"? Or "modern syntax"? Or CocoaJava?
And with hardware they had their "come to Jesus" moment a while ago. And then hit it out of the ballpark with Apple Silicon.
The one for software is still upcoming.
mort96 8 hours ago [-]
SwiftUI is too big to silently drop. It is too difficult to silently fix.
steve1977 7 hours ago [-]
So the only way out is something new again.
mpweiher 7 hours ago [-]
Happy to rename my stuff "Objective-Swift" :-)
joenada 10 hours ago [-]
Obj-C and Autolayout were absolutely awful to work with. SwiftUI is at least the right idea for a UI framework, it's just been implemented horribly.
lilbigdoot 15 hours ago [-]
I never really tried out Cocoa. What did you like about it?
steve1977 14 hours ago [-]
At least for me, it just had/has the right mix of
abstraction and simplicity. It just "ticked" in a way that for example MFC didn't.
But I also really liked Objective-C.
iainmerrick 13 hours ago [-]
Cocoa and Objective-C are both great, but I think there's one huge problem that they never managed to solve well: responsive layouts.
Classic iPhone apps have fixed layouts, and classic Mac apps have a big dynamic document in the centre with mostly fixed toolbars around the sides, and dialogs with fixed layouts. Making a really dynamic layout with OS widgets is a huge pain, so most apps sidestepped it.
As Apple gradually added more and more slightly different sizes of iPhone and iPad, making good UI layouts got harder. Even handling screen rotations is a huge hassle! If iOS had proper support for resizing from the start, screen rotation would be trivial, just another window resize.
Xcode had Interface Builder and autolayout, but I found those to be disastrously fiddly and unusable. Maybe some people like them?
HTML has many problems of its own, but it does have good support for responsive layouts. CSS isn't perfect, but it's vastly better than anything you can find in macOS, iOS, Android or Windows.
It seems to me that SwiftUI was trying to tackle two problems at once: React-style declarative UI, and responsive layout. Those are both good ideas, but trying to tackle both in a single uber-framework and deprecating the lower layers was too ambitious. As somebody said elsewhere in this thread, SwiftUI could have been decent as just an optional helper on top of the existing UIKit / AppKit.
steve1977 8 hours ago [-]
Maybe responsive layouts are part of the problem?
I get their appeal (in the sense of only having to develop one layout), but IMHO, in many cases more strict layouts would be the better choice.
You mention classic apps having a fixed layout, I think that's a good thing.
Not every user interfaces makes sense in portrait AND landscape mode for example.
And the slightly different sizes of iPhones are not really that problematic with something like autolayout.
iainmerrick 7 hours ago [-]
Well, you can still have breakpoints, and switch between different structures for e.g. mobile vs desktop, or landscape vs portrait.
But I don't think you can cover all requirements with a set of fixed layouts, they do need to be somewhat flexible. Even if all screens were the same size, you'd want to be able to boost the font size for accessibility, and that essentially means scaling the whole UI.
And the slightly different sizes of iPhones are not really that problematic with something like autolayout.
I think something like flexbox is a better fit. There are tradeoffs in each approach, but I usually find a local, modular, bottom-up approach easier to work with than global constraint solving, even though it seems in principle like it should be nice to be able to say "keep this button here in relation to this other button". As you add more constraints like that your layout slowly turns to mush and doesn't actually resize nicely. (Edit to add: I'm probably conflating a few different generations of iOS toolkits here, I realise autolayout is somewhat separate from constraint-based layouts.)
I don't think it's a coincidence that most other UI toolkits have added something like flexbox (including iOS) -- it's not perfect but it fits how people generally think about UIs. Was HTML/CSS the first major UI framework to use flexboxes? That's how I remember it, but maybe it was copied from somewhere else.
ben_w 6 hours ago [-]
> And the slightly different sizes of iPhones are not really that problematic with something like autolayout
It can be problematic regardless of the technical solution, though generally I have to agree with the loudest voices on this thread: SwiftUI is a load of rubbish, UIKit and autolayout (and Interface Builder) was better.
Regarding problems with all layouts: I've got a 2022 model iPhone SE, so smallest screen, and every so often run into an app which just doesn't handle the screensize right. I've seen this happen as a developer with both UIKit and SwiftUI, it's just the type of bug you end up seeing is different.
jstsch 10 hours ago [-]
Good points. It's just that responsive layouts have not been fixed anywhere. Also on the web, it is way too hard. How often don't you see a box floating over some background photo and then covering the focal point, e.g. the face? Sure, it can be done, but the permutations of testing are simply too large for mere mortals.
Multiple 'artboards' for screen sizes/ratios are the solution, which basically just means swapping out a .nib in Interface Builder. Better to just make it explicit.
refulgentis 1 days ago [-]
It’s a seductive idea, but it displaces who is responsible for the poor framework development onto users of the framework.
It’s easy to say they were just trying to be trendy and thus the real flaw was the trend is bad and the fault of worse devs than us (the young web devs mentioned)
The thing that obviates that is the trendy stuff works, yet, SwiftUI doesn’t.
(source: I wrote ObjC/Cocoa as early as 2006, and switched to Flutter as my primary dev kit some years ago: it simply doesn’t have the performance issues mentioned.)
pjmlp 15 hours ago [-]
It sure does, hence why there was this whole drama with a new render engine for Flutter.
refulgentis 8 hours ago [-]
Shaders compiled at startup vs. not, not “who knows why a repaint is happening”
pjmlp 8 hours ago [-]
It was a bit more than that, including how out of place it looked in fruity platforms.
refulgentis 7 hours ago [-]
No, they did not change the renderer because of Apple. That is a complaint about Flutter, the iOS-aping widget set can't stay up with current iOS, and I don't think they have a real solution yet. There's something about pulling out the Material UI library from Flutter itself that's supposed to help (I don't quite understand why, modulo "we can make a focused team work in a package instead of in the big ol' framework and that'll be easier")
Generally, it is not young web devs fault that SwiftUI exists, and certainly not their fault it still has serious issues 7 years in. The things named in the article as not-working in SwiftUI do work in fine in the others.
steve1977 2 hours ago [-]
Just to be clear, I don't blame young web devs for SwiftUI, I blame Apple for having tried to cater to them hastily.
sirwhinesalot 14 hours ago [-]
The problem with ObjC was mainly syntax, bolted on over many years on top of a C core. It was grown rather than designed, and it shows. But there's nothing wrong with the runtime.
Swift should have just been a much improved syntax over that same runtime. It would have avoided so many headaches. For one they wouldn't have made the awful decision to have return-type overloading and completely ruin the typechecker's performance in the process.
SwiftUI should have unapologetically been a convenient, reactive wrapper over UIKit and AppKit, rather than treating them as deprecated implementation details that devs nonetheless keep having to drop down into.
These decisions come down to ego, of wanting to do away with the old and carve out your own legacy separate from it. Nice if you want a promotion but not so nice if you're trying to make a long lasting ecosystem for developers to build upon.
At least Swift and SwiftUI have a reasonable interoperability story with the past. Can't say the same about Microsoft's graveyard of UI frameworks.
mbishop 9 hours ago [-]
Gotta take issue with the characterization of “bolted on”. That’s a design feature and it’s huge. It made interoperability trivial. You can write C, C++, and Objective-C within the same source file.
pjmlp 8 hours ago [-]
Including the CVEs from C style coding, a desgin feature it shares with C++.
mpweiher 13 hours ago [-]
> Swift should have just been a much improved syntax over that same runtime
That's exactly how Objective-Smalltalk started, and it's still very good at being just that.
> SwiftUI should have unapologetically been a convenient, reactive wrapper over UIKit and AppKit,
I am also working on a UI "framework" I call InterScript that is (for starters) a wrapper over UIKit and AppKit, and basically solves what I perceive to be the biggest problems of Cocoa:
1. UI specification using object literals. This makes UI-creation very compact and readable. The following example (mostly) reproduces a SwiftUI "Form" example from Apple documentation:
There are actually even better ways of accomplishing this, but this should give you an idea.
2. Better communication between model and UI by using the support in the language for polymorphic identifiers and dataflow. Because dataflow is in the language, it can be expressed succinctly without making it hidden magic like in SwiftUI. With dataflow and polymorphic identifiers, you also get a dataflow-constraint mechanism similar to Cocoa Bindings, but again with proper support and less magic.
There is more, for example cross-platform, MDA/Naked Objects/Direct2Web style simplification and web integration with HTMX and HTMXNative.
fidotron 15 hours ago [-]
The underlying problem is the programming industry completely resisting learning the lessons of Objective-C because it doesn't like them. It didn't like them when NeXT tried selling it, and it doesn't like it now.
You can't have Cocoa without Obj-C, or at least a langauge and runtime with that philosophy.
Apple software has been on a clear decline for a seriously long time, and it's propped up almost entirely by them pulling off Apple Silicon combined with how Microsoft have somehow been even worse.
layer8 14 hours ago [-]
As someone who hasn’t used the language, I’m curious about what the valuable lessons of Objective-C are that the programming industry is resisting learning.
jrmg 11 hours ago [-]
Weak, dynamic typing. Dynamic method binding at runtime (method calls really are message-sends). 'Traditional' object orientation with inheritance (although delegation and dynamic mixins are also core concepts, and the class hierarchy and method lists can even be manipulated at runtime). Nil is allowed anywhere and messaging (calling methods on) it is a no-op. Heavy use of 'notification' posting and subscription.
All of these are unfashionable nowadays, but they’re fundamental to Obj-C (some to the structure of the language itself, some just as idioms) and to the design of AppKit and UIKit.
Now, the fashion is:
Strong typing. Static binding at compile time with no runtime modifications to the type hierarchy. If OO is used, there should be minimal inheritance. Nullability is strictly defined in the type system, and acting on null objects causes, at its most forgiving, an exception, and at its least forgiving, program termination. Notification-based systems may be the outlier here (still in heavy use), but even they are often frowned upon for being too 'loose' and unanalyzable, at odds with the ideals of static typing and static binding.
mpweiher 11 hours ago [-]
Many, though I have to start with this disclaimer: I still don't fully understand why Objective-C is such a sweet spot.
One very important one is that, empirically, it showed how much of what we think we know about language design is ... shall we say ... "incomplete".
After all, Objective-C is a car-crash of a language: take some Smalltalk and jam it into C. Done. How can you write software with this? And yet NeXTStep and Cocoa/CocoaTouch, arguably the most elegant pieces of OS-level/UI-framework software ever, were written in Objective-C. And not despite of it, but because of it.
From a safety standpoint, it's hard to see how you can get worse: all the static type safety of Smalltalk (none) combined with the memory safety of C (none). And these interact.
And while it certainly is possible to use it very, very badly, in practice I haven't seen the horrors that we are supposed to get.
As an example, we got the same level of improvement from doing an Objective-C → Objective-C rewrite with Wunderlist (from WL2 to WL3) that others claim for Objective-C to Swift transitions.
Also, dynamic messaging is said to be slow, yet Objective-C programs consistently outperform the much more static Swift ones.
And of course, we all know that to do dynamic OO, you need a large runtime and better yet a VM. But it turns out that you can get much if not all of it with a tiny sliver of an extension to portable PDP-11 assembly language.
This! I remember reading 'Cocoa Programming for Mac OS X' by Aaron Hillegass and being fascinated by it. Coming from Java, C, doing some DSP code, web work, Objective C and Cocoa at first seemed just utterly alien and a bit wrong.
Message passing, these loosely coupled 'delegates', a mixture of hardcore C, needing to do memory management but also just passing objects around in the runtime... messy, weird... but in the end the right solution to make flexible but performant software. I learned a lot from it. I should dive into the history of NeXT one day.
dosisking 19 hours ago [-]
> Could Apple build MacOS X and Cocoa today if they didn't already exist?
Apple got rid of all the NeXT people long ago, with Tim Cook stabbing Scott Forstall in the back, so the answer is No.
saagarjha 11 hours ago [-]
This is completely false, many NeXT people still work there.
dosisking 10 hours ago [-]
So you think that they would be able to build MacOS X and Cocoa today if they didn't already exist?
dwaite 5 hours ago [-]
Would they want to?
If you were to build a system with no requirement for backward compatibility with cocoa or macOS, or even knowledge from such a thing existing, we have still moved forward three decades from not just NeXT, but the computing industry that NeXT was built to serve.
I'd assume their requirements would be drastically different, and the system they created would be drastically different as a result. The requirements aren't even easy to hypothesize, since iOS would never have existed.
saagarjha 10 hours ago [-]
In what sense?
ak39 17 hours ago [-]
This type of story about management getting rid of the old guard is so common and typical, it remains one of the most frustrating aspects of this industry.
In the “enterprise scene”, this sort of purge strategy is likely linked to a big percentage of money wasted and sometimes total failure.
Why do managers keep making this mistake? “Legacy” is only a bad word in IT.
:-(
mutkach 14 hours ago [-]
On the other hand, it is not uncommon for the exiled old guard to form new companies, teams, products and realize their vision under new management.
It is not like their knowledge and experience gets literally purged.
pjmlp 15 hours ago [-]
Because their KPIs are all about making a impact.
steve1977 2 hours ago [-]
Craig Federighi was working on EOF at NeXT I think.
mpweiher 1 days ago [-]
Not just complex. Also "successful for other reasons". And of course the RDF is particularly strong in Apple's case. And these are interlinked as well: they were successful in the past not just despite ignoring feedback/outside advice, but often because of it.
skydhash 1 days ago [-]
I think the main issue is the functional approach. Having a functional approach to state can be quite elegant, but ultimately the computer does not do functional. You have to implement a lot of plumbing to have stuff that is a bit performance (clojure), or just add a veneer of functional over what is essentially a normal state machine (emacs).
React works well, because it's only an abstraction over the real DOM. React only handles your app state. But the DOM mechanism is still very performant and very much imperative. But I don't think something like React would work well in a mobile app, because the UI tree is often very simple on iOS and macOS.
kikimora 17 hours ago [-]
Famous UI = f(Model) is oversimplification that was sold in slides. Real “functional UI” frameworks implement UI = f(Model, UIState) where UIState is scroll and cursor positions, view pool for virtualization, rendering caches, etc. USState is mutable and managed by the framework and the rendering engine (e.g. React + DOM, SwiftUI +
UIKit + CoreAnimation). I don’t see a problem with functional approach as in React. I do see a problem with understanding of how UIState being managed between framework, ui library and rendering engine.
mpweiher 1 days ago [-]
Not just does the computer not do functional.
UI is also very much not functional, and in fact the lack of progress in UI the last 30-40 years can largely be traced to trying to create UI with procedural/functional programming languages, an instance of linguistic-architectural mismatch.
Further reading:
Programs = Data + Algorithms + Architecture: Consequences for Interactive Software Engineering -- Stéphane Chatty.
Thanks for those links! Some of it was great reading.
What is your thesis then? What is UI?
mpweiher 14 hours ago [-]
"A view is a (visual) representation of its model. It would ordinarily highlight certain attributes of the model and suppress others. It is thus acting as a presentation filter."
View and model are related, but neither is procedurally dominated by the other. The view is not a subroutine of the model, or vice versa.
They are related entities that communicate in order for the view to function as a representation of its model to the user, and for the model to be manipulated by the user.
To get the details I really recommend the Chatty paper. It is a bit hard to read, but delivers the goods.
cloogshicer 7 hours ago [-]
Interesting, will check that out!
My working thesis is that UIs are basically video games. Just a gut feeling I can't really 100% put in words.
But essentially they're the same thing: Read input, update model, render view.
mpweiher 5 hours ago [-]
That's pretty much where immediate mode GUIs and to a less extent React came from. (Though for React the provenance is probably closer to the HTML web-app: send request - update model - return HTML with complete and completely new UI.)
The difference is that for most games, throwing away the complete rendered graphics and re-rendering from the world model is often the right approach.
For most UIs, it isn't, unless they really are very close to video games, for example mostly passive feed readers, video players etc.
cloogshicer 4 hours ago [-]
> For most UIs, it isn't
Why? Genuinely asking, this topic is very interesting to me.
mpweiher 36 minutes ago [-]
Because the UI is supposed to be stable.
jay_kyburz 10 hours ago [-]
Isn't that the Controller part in MVC
mpweiher 10 hours ago [-]
Common misconception, but nope.
The quote is from the original definition by Trygve Reenskaug, the inventor of MVC (see link above).
At each point you reify the result into an artifact that is everything the next stage needs. This has a couple of nice properties. One property is that everything is deterministic and testable. Another property is that after the pack and apply, everything is now embarrassingly parallel. Another good property is that you have an artifact that the accessibility people can latch onto before you bury it under pixels.
That would be a very functional way to deal with GUIs.
However, we continue inheriting properties and single main threading everything like we're still on 33MHz machines with 8MB of RAM.
mpweiher 14 hours ago [-]
>> UI is also very much not functional,
> I disagree, and I believe that the complete stagnation of GUIs is due to ignoring this.
1. What does that even mean? I don't see a UI in there at all, at best some graphics (Render).
2. That's not "functional". If anything, it looks like a pipeline, so dataflow. But then again, see (1)
3. Not sure why reification, that is turning things into objects, is functional to you. Reification, that is turning things into objects, is object-oriented.
4. MVC was actually created on 5.8 MHz machines with 128KB of RAM (including the display buffer). And still works beautifully today.
Functional is all about reification. You take a set of things in, you apply/map/collect/fold/whatever, you eject a set of things out. That is 100% functional--every time you supply the same inputs you get exactly the same outputs. The point of functional programming is that you avoid mutation and hidden state.
And, um, side note: dataflow programming is almost always considered functional programming.
Object oriented, by contrast, is all about hidden state and mutation. I send a message or call a function on that object over there and fingers wiggle and magic happens. But I don't know what or when or even if it actually happened.
And increasing evidence suggests that MVC doesn't work beautifully today because it doesn't parallelize, and it scatters state between uncooperative things. Just ask every single GUI that exists--every single one hangs because somebody made an oops and put too much work on the single, blessed primary thread. Or they have janky scroll. Or resizes leave gunk on the screen. Or your system flashes and jiggles because it's too busy reflowing everything in the universe. Or ...
mpweiher 12 hours ago [-]
You obviously have some very non-standard definitions at work here. apply/map/collect are just higher order operations, they have nothing to do with reification, except that you need the functions that are arguments to be first class.
> dataflow programming is almost always considered functional programming
That turns out not to be the case. Dataflow programming shares some aspects with functional programming, they are not the same at all.
> Object oriented, by contrast, is all about hidden state and mutation.
That also turns out not to be the case at all. Heck, there were even object-functional programming languages.
> And increasing evidence suggests that MVC doesn't work beautifully today because it doesn't parallelize,
What does MVC have to do with parallelization, in your humble opinion?
ardit33 15 hours ago [-]
You are applying a one way arrow to events where in real life events do change state and can completely change UI (and functions) itself. Which makes imperative always the superior mode.
What you described works only in super simple scenarios. Whink Web 1.0, when Javascript was used for basic form validation at best, and didn't change DOM that much.
torginus 1 days ago [-]
Imo the biggest issue with this functional model (at least in React), is that it handles things like virtualization, async, etc. poorly. Which is kinda ironic, because in a true functional language, it'd be feasible to provide 'a world model' - that is act as if the entire state is always available, and let the engine decide when to evaluate pieces of code - without any effort from the part of the programmer.
Unfortunately when complex state transitions, async, and virtualization enters the discussion, the magic of React breaks, and you have to deal with all that, and also deal with how React's engine handles things under the hood.
dminik 11 hours ago [-]
Stuff like virtualization (if we're talking about stuff like virtualized lists) is hard not because of React, but because there just isn't any support for it in browsers. React doesn't really help here, but in my experience, it's usually the browser that starts choking on high element counts, not React.
Async is just difficult in general though. It's not really a surprise that most libraries/frameworks converged on similar designs.
torginus 10 hours ago [-]
I am talking about virtualized lists. And it should be a framework feature. I used to use WPF on desktop, and it had pretty good virtualization support (though the framework in general was more like Angular) - most containers had virtualization support, and you only had to implement the logic on the data source, and they framework created and managed physical UI elements for you, and managed the mapping so it seemed seamless to the user.
React also operates on a virtual dom, there's no reason imo why couldn't they just fake that for you.
dminik 9 hours ago [-]
I mean, it's not quite that easy. The web is a lot more dynamic than WPF. If you just want virtualized homogeneous lists, there are libraries for that (and grids).
But, once you start hitting things like differently sized elements, search and so on, you start running into platform limitations that you won't be able to resolve in React land.
torginus 6 hours ago [-]
I know, that's why I said, that when you hit things like that (state that is too big to pull onto the client at once, and/or displayed at once), React's (and I guess a lot of other immutablity-based frameworks') dataflow management stops being magic, and you have to start tending to it.
Which usually means this model loses all advantages compared to simple MVC, or imperative systems, and at worst, becomes another headache as implementation details start leaking.
dminik 5 hours ago [-]
I guess my point was that it doesn't matter whether your framework/library is immutable/mutable/retained/functional/MVC/MVVM or whatever. You're hitting platform limitations one way or another.
But the rest of your app still gets the simplicity of a declarative programming model.
dgellow 1 days ago [-]
Hmm, but React doesn’t own or manage the app state. And react native has been used for pretty complex applications
poly2it 1 days ago [-]
Functional doesn't mean stateless. I'd argue functional programming is superior for representing state in user interfaces. For a success implementation, see Jane Street's Bonsai:
> functional programming is superior for representing state in user interfaces
It's always going to be slower than using something imperative. Trying to process the entire world's state for the sake of purity can feel elegant but it isn't free. And the complexity that gets added to make things performant is worse than just accepting that UIs are going to require you to jump around the tree and modify state.
Every time I go through the trouble of understanding the latest web technique (React, Elm, Signals (the newest solution), etc.) to deal with state management and the DOM, I end up walking away disappointed. There's nothing new in them that you can use to improve what we've been doing for ages in native GUI toolkits.
And to jump back to the original topic, yes, Cocoa was pretty decent, and SwiftUI while nice in many ways tries to Reactify native macOS development and made it worse. And it made Swift incredibly more complex and worse in hindsight.
kodebach 1 days ago [-]
The goal of the reactive/declarative approach was never to be more performant than imperative code. The goal is to more easily build UI that is performant enough and functions correctly. With imperative UI code it is incredibly easy to forget an edge case in your update logic.
mpweiher 1 days ago [-]
Not if you actually do MVC, so solved around 50 years ago.
1. The UI tells the model to change.
2. The model does the change and possible related changes.
3. The model notifies the UI that something has changed.
4. The UI updates itself from the model.
Alas almost nobody does MVC, despite calling what they do MVC.
kikimora 17 hours ago [-]
MVC is not bad, but it is not a silver bullet. Calling MVC an ultimate solution to UI is oversimplification. Just looking at the steps you listed I can ask:
How do you collect all notifications on step 2 to fire them on step 3 such that UI does not re-render itself too much? E.g. updating a title of each item in a list of 100 items should not trigger 100 renders. Or 100 layout calculations (which I think is harder to avoid).
How do you deal with situations where on step 4 UI triggers an event that your model happens to listen and the cycle repeats while killing performance?
Because you rely on events how do you avoid “event hell”? That is, a situation when an event handler triggers a change that triggers another event handler that triggers a change and so on. Sometimes it is scrolling or typing, sometimes it is parts of the model subscribed to each other bubbling events to UI.
mpweiher 14 hours ago [-]
I never claimed MVC is a silver bullet. Just that it solves "... incredibly easy to forget an edge case in your update logic."
> UI does not re-render itself too much?
Glad you asked! In my Blackbird reference architecture (which is an instance of MVC), I use a coalescing queue to capture the updates. The coalescing is two-level: first, simple duplicates are weeded out. Second, if the update queue gets very full, it becomes coarser-grained, and weeds out duplicates based on that coarser grain. This has multiple steps of grain up to "just re-render the whole UI". Worked like magic in Wunderlist. Except it wasn't magic at all and very simple, inspectable and tractable.
> step 4 UI triggers an event that your model happens to listen
That's not allowed in MVC.
> Because you rely on events how do you avoid “event hell”?
I don't "rely" on events and there is no "event hell". Events are only used in the M→V communication part and there are no subsequent triggers, because the only event is "the model has changed", with an optional payload specifying which part of the model. Important: it must not contain the data that changed, this the view has to fetch from the model once it processes the update event.
Since the only event used is "the model changed", the view cannot ever be a source of those events, so no "event hell".
layer8 13 hours ago [-]
How do you handle UI state vs. underlying data (model) state, and dependencies between them? By UI state, I mean things like scrollbar position and selection state. When displaying a scrollable and selectable list of items, then for example when the number of items changes, the selection may need to adjust, and the scroll position may need to adjust. Depending on which items are added or removed (or reordered), the selection and scroll position may need to change differently for the apparent UI state to look stable for the user. If only the model is changed, a previous UI state like selection or scroll position may become invalid in relation to the new model state. Who updates the UI state accordingly to make it valid again? In the general case, application code needs to be involved in choosing the desired valid UI state when the underlying model state changes. How is the corresponding application code prevented from triggering further events?
mpweiher 8 hours ago [-]
>How do you handle UI state vs. underlying data (model) state, and dependencies between them?
I don't. And I don't have to, as I delegate that sort of stuff (mostly) to Cocoa/CocoaTouch etc.
When you have stateful view objects, these stateful view objects maintain the view state. When updating themselves with new data due to a ModelDidChange notification, they take care of reconciling their current display state with the underlying model state.
> When displaying a scrollable and selectable list of items
So for example an NSTableView or NSCollectionView. I personally use a subclass that interacts directly with a table representation, meaning a lot of the glue code that Cocoa(Touch) requires disappears.
> Who updates the UI state accordingly to make it valid again?
Always the view. Who else?
> In the general case, application code needs to be involved in choosing the desired valid UI state when the underlying model state changes.
How so? The view is always a reflection of the model data. Whether that is a "change" is actually mostly irrelevant, even though the notification is called ModelDidChange in my case. In Smalltalk MVC it is the #changed message. It means "you are out of date, please make yourself reflect the model".
This same mechanism also handles the model being changed by some other party without any further code. "The model has changed, please update yourself to reflect the current state of the model". That's it, modulo optimizations.
> How is the corresponding application code prevented from triggering further events?
Model code isn't involved. A ModelDidChange event is only triggered when...er...the model changes.
That said nothing prevents you from manually invoking the ModelDidChange notification, just like nothing prevents you from calling abort(), running an infinite loop, creating an unbounded recursion or reading from /dev/random until it is exhausted ...
Doing it by accident, though, is very hard, because it just isn't part of the programming model.
kikimora 14 hours ago [-]
>The coalescing is two-level: first, simple duplicates are weeded out. Second, if the update queue gets very full, it becomes coarser-grained, and weeds out duplicates based on that coarser grain
This is not about duplicates. For example, sync updates 100 items in a list changing their titles. Items are bound to a list in the UI. Thus, 100 unique title update events triggered.
>Events are only used in the M→V communication
I don’t understand. Button clicked -> model change -> view update -> new event triggered -> model or view updated again … This is not something one would code on purpose, but often an attempt to create relationships between view. Like a custom layout code. Might not include model at all, just views being updated in an event handler trigger more events and more updates to views.
mpweiher 11 hours ago [-]
> For example, sync updates 100 items in a list changing their titles. Items are bound to a list in the UI. Thus, 100 unique title update events triggered.
Those "updates" go in the queue. When the UI gets around to updating itself, it looks at the queue and invalidates all the UI elements that refer to the model items in the queue.
It then updates those elements, using the coarsening to update larger elements in bulk if that becomes better.
> Button clicked -> model change -> view update -> new event triggered -> model or view updated again
Once again, that is not allowed. View updates are not allowed to trigger any events in MVC. A model → view update updates the view. That's it.
The only event is "model changed", so it also doesn't make sense for the view to generate those events.
fschuett 10 hours ago [-]
I can only say how I did this in the Azul GUI framework[1] (note: not production ready yet), which may be close to what you're describing. So in Azul, you do this:
So, there's no "automatic" re-render, a callback has to return "Update.RefreshDom" or "Update.DoNothing" (default).
Now to your questions:
> How do you collect all notifications on step 2 to fire them on step 3 such that UI does not re-render itself too much?
Diffing, and then caching very aggressively. The click causes the model to re-call the layout() fn to return the entire DOM, however, there are ways to make this step very fast (arena allocation / no allocation). Then this gets diffed with the previous DOM state and the framework internally reuses everything it can (with user providing keys for list items, like React does).
> How do you deal with situations where on step 4 UI triggers an event that your model happens to listen and the cycle repeats while killing performance?
Azul has a "max recursion depth" of 5 and then just throws an error (infinite cycle). So, it will invoke all the relevant callbacks for a frame, then "sum up" all of the Update enums (i.e. one callback returned RefreshDom -> now we need to repaint).
> Sometimes it is scrolling or typing, sometimes it is parts of the model subscribed to each other bubbling events to UI.
Scrolling, selection, typing, etc. are handled by the framework. To make something editable, you need to set "contenteditable=true" on the Dom node (like on the web). Then, on text editing (which can also come from IME, a11y input, copy-paste), you get a "text changeset". The callback can then "reject" the changeset or allow it (default, since you already set contenteditable before).
Azul has a "dual update pattern" for performance here, i.e. the DOM itself is immutable until the next layout() call, however for "quick edits" like dragging a node you obviously don't want to call layout() again and construct an entire new DOM tree. So there, you just (conceptually, don't know the current API for this):
def on_div_dragged(data, info):
mouse = info.get_window_state().mouse_state
info.set_css_property(info.get_hit_node(), "transform: translate(%s, %s)", mouse_state.x, mouse_state.y)
# store in data model or node if necessary
data.user_mouse_pos = mouse_state
return Update.DoNothing # no re-render here
So, if another callback fires in between, the data model is still properly up to date. Azul also aggressively reconciles focus, scroll position, selection, text cursor position, etc. But Azul does not allow "one event auto-triggers another" like SolidJS does, it looks nice on a slide deck and then is a pain to debug Rube-Goldberg state machines.
This also works for text input or updating images (i.e. you don't need to call layout again on text input). Update.RefreshDom is for "larger / structural" changes, i.e. something like a route switch in a SPA-style app. Azul tracks the text cursor position by diffing the actual text, so the user code doesn't have to track the text cursor and state is preserved during a diff (it can also retain heavy elements).
For large lists, there is a native "virtualized view" DOM node with a callback that is being called "during" layout (after the size of the container has been determined, then the framework asks you to render your DOM, given the scroll position). So, that can be diffed, too. You never render in the DOM more than ends up on screen, so the perf is manageable.
Scrolling and retaining scroll positions inside a virtualized view is still an ongoing topic (not impossible, you just have to have functions to measure the DOM items before you return them, to estimate how much you need to render, and then do the math for "where are we right now, where is the scrollbar, how big is the virtualized view in relation to what we're rendering" - so the framework can set the right scrollbar size and position).
Again: please don't use or post Azul here on HN yet, docs are still slop and undergoing review, API is unstable until I have some apps going, but I just wanted to answer these questions.
Is the UI updating itself automatic or manual? Because if it’s manual, that’s precisely the error-prone part that you’re saying this approach somehow solves - you’ve done the “How to Draw an Owl” meme. If it’s automatic, that doesn’t seem especially different from the React/Redux/Elm/SwiftUI approach (as a sibling points out).
mpweiher 14 hours ago [-]
Yeah, M-V-C are all roles, not concrete objects. The C mediates between the input devices and the model, but in practice views can and often do fulfill that role as well. Cocoa views, for example, also fulfill the C role.
Different formulations of M-V-C have the C deal with more complex interactions, with sequences of interactive prompts like wizards.
The update is essentially automatic, and yes: MVC already solved the "problem with MVC" React/Redux/Elm/SwiftUI claim to solve. In 1979.
jay_kyburz 10 hours ago [-]
I like my Controller to be responsible for all the "business logic" so that its all in one place. It's the important part. The View layer is always fairly verbose and full of fluff. Especially if you have a lot of animation and formatting type code.
mpweiher 8 hours ago [-]
> I like my Controller to be responsible for all the "business logic" so that its all in one place.
Business logic is supposed to go in the model. All of it. Because it's the important part.
Controller these days can be largely empty.
"MODELS
Models represent knowledge. A model could be a single object (rather uninteresting), or it could be some structure of objects.
There should be a one-to-one correspondence between the model and its parts on the one hand, and the represented world as perceived by the owner of the model on the other hand. The nodes of a model should therefore represent an identifiable part of the problem.
The nodes of a model should all be on the same problem level, it is confusing and considered bad form to mix problem-oriented nodes (e.g. calendar appointments) with implementation details (e.g. paragraphs)."
Are you saying the UI always updates its entire self whenever anything changes in the model?
mpweiher 14 hours ago [-]
Yes and no.
Conceptually, the UI re-renders itself completely in order to always be an accurate reflection of the model.
That is the #1 job of the view: be an accurate reflection of the model.
And re-rendering itself completely is a safe way to implement that requirement.
However, the UI can also look at the model in more detail and figure out what parts need to change, as long as the effect is the same as re-rendering everything.
And the model can tell the view that specific subparts of the model have changed to make that job easier for the view.
But if it can't figure out the details, the fallback is to re-render the entire view from the model. But not to recreate the view. The view sticks around.
One way of doing this optimization is "damage rects" like Cocoa does. Another are the polymorphic identifiers used in the update queue of Blackbird.
jay_kyburz 10 hours ago [-]
Immediate mode UI ftw.
ardit33 15 hours ago [-]
Dude, you didn't describe MVC at all, but MMVC.
MVC, the controller is the intermediary between the services/data models, and the views.
That still one of the best / simplest way to build large apps. MMVC is just a variation of it, with the models being able to communicate state to views and bypass controller if needed.
MVC, is still one of those 'fundemental as simple as it gets, and it gets the job done' patterns.
mpweiher 14 hours ago [-]
Dude, what I describe is exactly MVC.
Your interpretation is a common misconception, for example promulgated by Apple. It is not MVC.
Not sure how you define "success" here. Is Bonsai used much outside of Jane Street?
skydhash 1 days ago [-]
> Functional doesn't mean stateless.
I didn't say that.
User interfaces representation are mostly trees. And with functional programming you basically have Tree2 = f(Tree1). Until f is done you can't do anything really. React has a lot of escape hatches to improve performance, but they are escape hatches, not an endorsement of the architecture.
With imperative programming (and OOP), you only have that single `Tree`, which you update at will. Less elegant yes, but we have modularization to help us there. What Emacs does is to keep that `Tree` as a single mutable object, but have the code be functional, while the results are imperative.
zombot 17 hours ago [-]
> I wonder if we'll say the same thing about Apple 10 years hence.
I don't think we have to wait 10 years, we can say it today.
simondotau 15 hours ago [-]
That wasn't the question though. Being able to say it today doesn't mean you will be able to say it in 10 years. Companies which lose their way sometimes rediscover themselves. One example that comes to mind is Apple. Another example that comes to mind is Apple.
In fact I can think of at least three instances (at very different magnitudes) where Apple has dragged itself out of a stupid hole they dug for themselves.
ransom1538 9 hours ago [-]
"ship a true successor to Win32 suggests that Microsoft"
Because it was good.
estimator7292 20 minutes ago [-]
[dead]
brnt 1 days ago [-]
I only have to look at the iPhone fucking 17 to know Apple is long gone.
graypegg 1 days ago [-]
Genuinely curious, what’s wrong with it?
I’m no huge apple fan, but I didn’t really think the 17 was more than a regular boring spec upgrade, which seems fine all things considered. (Currently on an iPhone fucking 17)
brnt 14 hours ago [-]
Apple did not use to be in the business of producing version 17 of something.
steve1977 2 hours ago [-]
Apple was once in the business of producing Performa 630, 631, 635, 636 etc.
stasomatic 10 hours ago [-]
Where?
sandoze 1 days ago [-]
This seems to be a popular ‘controversial’ topic. I’ve been using SwiftUI for production applications and games since 2021. I drop down UIKit, Metal, or core animation when needed. But that’s no different than when I was making games in UIKit and would drop down to core animation or glyph renderers written in C etc.
Data Flow: The author claims there’s no way to know when things update. Not only does experience help here but there are profile tools that tell you when and where things are updated. This isn’t black magic. Keep Views small, be careful how you hand around data. @environment is super cool but can have a cascade effect. This was greatly improved iOS 17+ and I wouldn’t support anything older than iOS 17.
GeometryReader: Occasionally I’ll use this. It’s kind of a necessary evil when dealing with certain view complexity. It can also be a sign that you’re doing something wrong.
API Stability and performance: Apple users upgrade. There’s no reason that you should be supporting iOS 17 at this point — even iOS 18 is roughly 2%% of our user base across several apps. I’ve been using SwiftUI without major performance issues but I also don’t early optimize. I profile and fix as needed. One of the early studios I worked for wrote all our games in UIKit as prototypes, when performance tanked we’d switch to the appropriate tools (eg. OpenGL) where it was necessary — like in the core game.
I could go on but in the end just use the right tool for the job, if you’re not proficient in SwiftUI or it isn’t going to work for your cross platform project, you have a lot of other alternatives. For me though, it’s been amazing to work with. I stepped away from iOS programming for 3 - 4 years because I was burnt out using storyboards, dealing with massive view controllers, and all the boiler plate it’d take to get a view up and going in UIKit. SwiftUI roped me back in.
* Quick addition edit: Cross platform for iOS, iPad, macOS has never been good. I’ve found recent updates have made things better to the point of tolerable and it’s nothing like when we had to post-fix an ~ipad to our Nibs — There has never been a ‘glory days’ of cross platform Apple UI libraries.
_s 18 hours ago [-]
I was just thinking more or less along these lines - I haven't been in mobile apps for a few years now, but back then my impression was -
SwiftUI is great for "surface level" UI, that has some basic data bindings - think a basic CRUD app, which needs some navigation, and the ability to scale across the smallest iPhone to the largest macOS screen, from touch gestures to mouse input.
If you ask anything more of it, then you need to start branching off into specific libraries / tools / frameworks (UIKit, CoreAnimation etc) - which is much easier now too, but you'll always have a bad time if you try to mix the two in a single "view" / "frame".
I'm not surprised that's still true today.
Exoristos 18 hours ago [-]
It's a popular controversy here much the way React is a popular controversy here: people dabble in the new idiom but don't solidly master its basics; chaos ensues and consequently resentment.
joshuakcockrell 18 hours ago [-]
Complaining about needing special code to support iOS 15 definitely weakened the argument.
VerifiedReports 16 hours ago [-]
"@environment is super cool"
Strong disagree on that. @environment is an amateurish hack, basically sugar-coating global variables as a solution to SwiftUI's poor design.
I had a strong background in UIKit; then for a product I'm building for myself, I decided to go all-in on SwiftUI. This was after it had been around for four years or more.
SwiftUI turned development, which I used to enjoy and feel good about, into a tedious trudge. I read everything I could, did the Stanford class, adopted "best practices," and really made an effort to do it right. It blows.
Unless your app is a trivial master/detail data-viewing app (as pretty much every SwiftUI example is), you wind up thrashing and performing all kinds of state-tweaking gymnastics to herd your application along through whatever tasks the user is supposed to be doing. Heaven forbid you need to walk the user through a series of steps to do or create something.
It's going to be a testing nightmare, and it suffers from every bit as much opportunity for data to get out of sync between the model and the UI as "traditional" app structure. Apple touts the "single source of truth" as gospel in SwiftUI, but you can't have that.
First of all, Swift's official position is that you should "prefer structs" over classes. But (and this is one of Swift's hokier characteristics) structs are passed by value (copied) instead of by reference. So your "single source of truth" is broken after the first function call; your data are copied all over the place.
But there's another problem with the single-source mantra: You can't just expose your core model to the UI for direct manipulation, so you have an intermediary (the so-called "viewmodel"). But that intermediary must have temporary data structures to shadow those in the core model, so the UI isn't messing directly with the model, and the user can cancel or fail when changing things without messing up the integrity of the model.
So now, once again, you don't have a "single source of truth."
The problem isn't understanding the paradigm; it's making it do useful work. Some people love to mock OO for its early and obviously cumbersome and pointless idioms, which were quickly abandoned by experienced programmers. What remains of OO is still quite useful.
I predict the same for... whatever the this mess is called. You waste so much time trying to follow the gospel of "MVVM" for no actual benefit. As I went through it, re-reading and re-digesting various pundits' viewpoints... I realized that I just had to start from scratch and build something that pays off instead of a bunch of useless ceremony.
I switched everything to classes, built managers (controllers) for the big categories of data and tasks I need to organize, and inject whatever objects I need into each view.
As for the rest of SwiftUI, its state is disgraceful. It excels at scaling UI for different screen resolutions; something that Apple neglected for waayyyyy toooo long. But there was no excuse for Apple to release a UI framework that basically didn't support the most fundamental UI paradigm of phone applications: a stack of progressive views that are programmatically manageable.
How many half-assed attempts has Apple trotted out, to do what UIKit does with ease? The latest is NavigationStack, which is still pathetic. The only way to navigate more than a level deep is to create an array of one datatype to serve as NavigationStack's "path." But this is designed to be an array of a single datatype. Look at the examples for this thing: They're applications that present a stack of views that each show... an INTEGER. In decades, I have never written an application that needed to stack up a pile of views that all show the same datatype.
And yes, I know the workaround for this where you create your own struct datatype and then fill it with enums, one for each view. But come on; the fact that Apple even rolled out this ludicrous design tells you that the talented architects have left the building.
sandoze 7 hours ago [-]
I don't want to downplay your lived developer experience, I'm not fully following all your arguments but let me just say @Environment is a great tool. We've all used singletons, even more so in UIKit seeing how unintuitive key value observation was.
It's used a few different ways in the app I'm looking at now. One is to hold a source of truth for my API data models. This way I have a cache of say User that, when it changes for whatever reason - maybe invalidating the cache (read logout) or changing a profile image - is handed around to all my Views that need User info with @Environment(\.user)
Same thing with my analytics. Something like a MixPanel is only going to be created once. It's a singleton. You pass it around in an @Environment.
NavigationStack was a problem pre-iOS 17 and even a bit of a jam in 17 -> 18 and was glad to drop that version. But passing around an enum of values makes deep linking intuitive, yes there's a bunch of boiler plate - setting up an enum I guess - but deep linking was never easy. If you're not doing deep linking then a NavigationPath is really simple to use but I assume that's not what you were talking about.
I used MVVM for about 6 months and ripped it out. There's no reason to use that pattern in SwiftUI. It was popularized by certain iOS evangelists and caught on with the newbies (myself included). Your reaction to MVVM and useless ceremony is exactly the response you should have to a code smell that doesn't belong and it was mine too.
willtemperley 15 hours ago [-]
> The latest is NavigationStack, which is still pathetic. The only way to navigate more than a level deep is to create an array of one datatype to serve as NavigationStack's "path." But this is designed to be an array of a single datatype.
You can use a tagged union for the "one datatype", thereby allowing your views to accept any datatype you provide in the enum. Or use NavigationPath.
troupo 8 hours ago [-]
> Unless your app is a trivial master/detail data-viewing app (as pretty much every SwiftUI example is),
And it's pretty much incapable of making anything that is not a master/detail with endless lists within lists within lists.
Just look at the shit that Apple regularly ships now: it's just endless lists of lists.
mintflow 18 hours ago [-]
As a solo app developper for two years mainly for apple platform(previously do networking infra software using C/Go)
After two many trial and fail, now it's quite clear to me that for simple UI I will use swiftUI(such as help sheet or simple toggles), for complex and performance first, I will just use UIKit instead, it save a log of time and actually the imperative UIKit is also quite easy to read and review
the feasibility of review is important because code is not mainly written by agent, though as my understanding of UIKit grows I can smell the bad part and let it rewrite
il-b 14 hours ago [-]
Somehow, we’re still failing to realize that the most complex UIs - think CAD software, 3D editors, etc - are imperative, object-oriented, and written in C++. Their core development teams are usually very small. Yet you need a 20-person frontend team to deliver a primitive e-commerce app. It’s as clear as day that the promise of declarative and reactive programming is failing its users.
dminik 9 hours ago [-]
How much of this is that most of these tools have been around for 20+ years and come from a time where OOP was the holy grail coming to save humanity?
jonhohle 8 hours ago [-]
I think the key is these things were possible 20 years ago with small teams and now large teams and even teams at Apple can’t make competent apps with the flagship product.
I worked at a FAANG and a team was tasked with implementing a new REST framework to replace/augment the supported RPC framework. Metrics were very important and this team might have know HTTP/REST well, but they didn’t understand what operators needed. It wasn’t even on their radar. As a senior engineer, without much traction I complained and fortunately someone one level higher from across the company saw my message and had the necessary influence to get them to pause and think. I don’t know if anyone has done that at Apple.
Things that used to work universally - key bindings, drag and drop, context menus - just don’t work by default anymore. Why? Because now everything is some low level UI element and whose behavior is completely up to the programmer. Sounds like web programming, not like Mac programming.
From a programming perspective, I don’t even like the paradigm. Once understood, IOC in AppKit and Interface Builder was incredibly efficient.
dminik 8 hours ago [-]
No offense, but this doesn't seem like a realistic way to look at things.
Autodesk (since you mentioned CAD) itself dates back to 1980s. And even then, they had at least 15 people working on AutoCAD. That's a small team size. Today, they have over 14000 employees. Some random website tells me they had ~5000 of them 20 years ago. You can make anything work when you throw an army of people at it. It's not exactly a good point towards small teams being able to build complex imperative/OOP apps.
That's not to say that Apple is not dropping the ball here. I don't really have any Apple devices to check for myself, but I know that Microsoft, for instance, has been doing much more than just dropping the ball when it comes to UI. But, I'm not sure that has anything to do with imperative vs declarative.
cosmic_cheese 1 days ago [-]
I'm sure many will disagree, but I have doubts that pure declarative-reactive is the "right" shape for an all-purpose native UI framework. In my experience, Kotlin+Compose shares many of the same warts… its main redeeming quality is that it's better than Android Framework (most of the time), which is low bar to clear.
These frameworks have a number of good ideas but they don't necessarily combine in a way that transcends high quality traditional imperative frameworks with declarative-reactive bits sprinkled throughout, at least for more complex apps. SwiftUI and its ilk work best for super simple tabs-and-flat-lists sorts of apps.
rumori 1 days ago [-]
I think open source is the right move here. The great thing about Flutter is you get the declarative UI to build a lot of standard screens easily but you can always drop down to lower levels, inspect the standard components, mix and match with your custom implementation.
You can mix UKit and SwiftUI but there’s way more friction due to the closed nature of the SDK.
norbert515 1 days ago [-]
Fully agree (been an early Flutter adopter!). It's always the right too for the right job, declarativness makes a lot of sense for most UIs. UIs are surprisingly more complicated than one might think, there is accessibility/ theming/ keyboard traversal etc., just declaring UI and letting the framework figure out the rest has held up pretty well.
And because of the open source nature you can always drop down in layers, just a few weeks ago I made a very specific engine optimization, all while the application code on-top can stay declarative!
cosmic_cheese 1 days ago [-]
Perhaps. Certainly source visibility makes life easier as a dev who has to live with these frameworks on a daily basis. That said, I think frameworks should strive to have a wide and deep enough set of widgets that in most cases, devs won't need to resort to custom implementations to do what they need to.
It also doesn't fix problems inherent to declarative UI, like readability breaking down easily and certain things that would be a cinch in an imperative framework being extremely awkward to implement.
dminik 8 hours ago [-]
To make complex layouts (flex, ...) and have them run performantly you need some form of a retained backing state anyways.
The main difference between various retained, OOP, functional, immediate, declarative, ..., approaches is how they treat this state.
For imperative/retained/OOP libraries, you operate on this state itself. Your nodes/widgets know their own state, how to render themselves, their place in the hierarchy and so on.
For immediate/functional(?) libraries, this state is a cache. It's not something you work with directly.
Despite not really liking React itself, I think it has found the best model.
You take a retained core, possibly OOP, maybe ECS or whatever, and you write a declarative wrapper around it. This lets you escape the easy-mode declarative landscape when needed, but most UI can still be simple to write.
kodebach 1 days ago [-]
Do you have an example of where "the ideas don't combine well"? Or where an imperative approach is truly better?
In my experience the solution is often to use the appropriate architecture underneath your UI layer. Basically you build a data structure that represents your UI and always hand this entire structure to the declarative UI layer. Underneath the UI layer, you can still use imperative code to manipulate the data structures. The benefit of the reactive/declarative approach is that you don't have to think about how changes in the data need to be reflected in the UI. That's the framework's job.
Note: With "data structure" I don't mean "build a shadow DOM". I mean something specialized to your use case.
cosmic_cheese 1 days ago [-]
One example of where I think imperative generally does better is UI that requires substantial setup or customization.
In SwiftUI, that means endless chains of modifiers, and in Compose this means monstrous constructors and modifier chains. Both get really ugly and painful to read quickly, and there's not a lot that can be done about it apart from breaking everything out into smaller views (which only goes so far). The amount of boilerplate saved isn't worth the trade, in my opinion.
In an imperative setup, there's still a lot of code but there are more options for organization, readability, and overall clarity. One can break things up with comments, break out setup into functions with self-explanatory names (that the IDE can then quick jump to, as a bonus), etc.
Yes, it's easier to get tripped up with imperative frameworks if one isn't thoughtful with managing their data, but much of the time that code only needs to be gotten right once.
well_ackshually 13 hours ago [-]
>in Compose this means monstrous constructors and modifier chains.
I agree, the first section "Data Flow" reflects my concern with Compose as well:
> Data flow in SwiftUI is indeed reactive—but sometimes I wish it wasn’t, because it’s reactive in all the wrong ways. It often reacts to changes it should ignore, and it ignores the changes you actually care about. To me, SwiftUI’s reactivity is a black box: It makes achieving predictable behavior almost impossible.
In Compose, seeing rememberXXX(key1, key2) sprinkled all over with keys makes following the code difficult.
Then add some side effects like LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { ... read permissions and render warning if we can't do something ... } and it becomes even more difficult to comprehend. Much of the Android framework APIs are not reactive, and polling on these UI events is still necessary (permission could have changed if the user put the app in the background, and you can't listen to them via Flow etc).
As the author says, these frameworks make the static data dependencies explicit but often at the expense of what is changing and why.
When I see rememberXXX(key1, key2) { } the first thing that comes to mind is, why would key1 and key2 change, and often that is not obvious.
spacedcowboy 1 days ago [-]
Apple had a real winner with ObjC and AppKit. Swift is horrendously complicated for the benefits it offers over ObjC, and SwiftUI is a massive step backwards from AppKit.
Just MHO, and it’s not going to stop the juggernaut, but there’s just no appeal in moving there for me :( If (when ?) Apple drop ObjC, that’s the day I move to Linux
happytoexplain 16 minutes ago [-]
All of Swift's complexity is opt-in, thoughtful, and domain-specific. It's the exact correct type of complexity.
SwiftUI is not Swift. It is implemented using complex Swift features, but it is a huge step backwards in dev-ex from autolayout and UIKit.
blltprfmnk 1 days ago [-]
There were a lot of people actively complaining about ObjC in the lead-up to the unveiling of Swift. In fact I recall one prominent blogger in the iOS community begging Apple just a few months earlier to consider replacing it.
Unfortunately although Swift seemed promising at first, by the time Swift 3 rolled around a lot of people were actively frustrated and moved on from iOS development. Having actual experienced hands guiding that ship could have led to something great instead of the mess that is there today.
spacedcowboy 14 hours ago [-]
Most of the complaints about ObjC seemed to be from the “weird bracket syntax” folks, at least the loud ones.
Memory management, Generics, Fast enumeration, Properties were seamlessly added to ObjC over the years without adding to the cognitive load of the language, which is minimally more than that of C. It’s a small superset of C and (for me) hits that complexity/expressiveness sweet spot. YMMV, of course.
jonhohle 8 hours ago [-]
It would be interesting if instead of a new language the Objective-C compiler enforced a a memory safe version of C. That’s the biggest advantage of Swift, imho.
I hated the properties addition in Objective-C. Why add that and not a dot syntax for all messages? Having a dot operator in a pointer blurred too much of the line between C and Obj-C syntax for my taste.
kccqzy 23 hours ago [-]
Are you talking about the unveiling of Swift or SwiftUI? My recollection was that some people hated ObjC and wanted a more modern language. Apple gave them Swift. But I don’t recall people hating AppKit (maybe I wasn’t remembering correctly) and SwiftUI was basically Apple following the hipster trend.
blltprfmnk 23 hours ago [-]
Just referring to Swift.
Agree that SwiftUI was just jumping on a bandwagon and would say that the design of SwiftUI clearly strains the poor language design choices in Swift.
frizlab 1 days ago [-]
Having written actual apps with AppKit, it is horrendously complicated for simple things.
Swift is incredibly better than ObjC on so many ways it’s just not comparable. I used it since day one and never looked back. (And I was deep into the ObjC ecosystem, having written very low-level frameworks, and having loved it.) Yeah, first versions of Swift were raw, but now it’s just THE language; I used for everything (obviously Apple soft frontend, but also the web, the backend, etc. Even android dev I would do with Swift though I do not have the occasion for now.)
Apple will never drop ObjC support IMHO. But most new frameworks will be Swift-only.
SwiftUI is a step backwards from AppKit in the sense that we lose control over what’s possible when using it exclusively. But 1/ it’s much simpler for doing simple things and 2/ we can drop down to AppKit when needed. All in all, it’s good that we have it.
troupo 8 hours ago [-]
> But 1/ it’s much simpler for doing simple things and 2/ we can drop down to AppKit when needed.
New things (especially 12 years on) shouldn't be "do simple things simpler, and drop down to old ways for complex stuff". It should be "do complex things simpler".
polyterative 7 hours ago [-]
I strongly disagree.After many years in software development, I'm sick of resolving the same issues all over again.Make me write less code, make me spend less time fixing it.That's what is increasing productivity and scope for my projects.
troupo 7 hours ago [-]
> I strongly disagree.
You strongly disagree with what? That new tools shouldn't just make simple things simpler?
> Make me write less code, make me spend less time fixing it.
But that's exactly where SwiftUI fails, doesn't it? The moment you step outside the "the only UI you can do is lists", you are exactly in the "write more code with weird failures" territory with "just fallback to AppKit for anything even slightly outside of the extremely limited sandbox".
jshier 1 days ago [-]
Apple will likely never drop Obj-C, but it's been a secondary language for years now. New frameworks are all written in Swift, Obj-C is only used for existing Obj-C codebases.
joshuakcockrell 18 hours ago [-]
Ah yes, the glory days when you had to sift through 200+ lines of NSLayoutConstraint just to fix a simple layout bug.
happytoexplain 11 minutes ago [-]
This is the main "problem" with autolayout. It's an amazing experience that "just works" if you think in the way that autolayout asks you to (relativity, declarative, the idea that each dimension is fully defined by exactly two constraints, isolation of dimensions aside from aspect ratio, etc).
If you don't think that way, or you're debugging somebody else's layout, then yeah, it's a nightmare. But it's shockingly easy to just redo the whole layout in that case.
ardit33 15 hours ago [-]
Just use manual layout / frames dude, like a caveman. (ps. Many successful large apps do just that, including Instagram, and some of Spotify, where I worked).
Alex_L_Wood 3 hours ago [-]
I think SwiftUI is just a reflection of the times we live in. If you look around, many things which used to be done at "great" or "amazing" levels, are now just "good enough". Cars, houses, software, service - it all is just a reflection of the attitude, and even I noticed that I follow this in some of my day-to-day decisions.
sujee 12 hours ago [-]
I have recently completed building a large native macOS app and my take is that, for 90% of work, SwiftUI is good but for the 10% you would need AppKit.
For my app which is a AI chat app, I needed to load and show a large number of chat items in a list, SwiftUI is really bad at this. Another issue is, most of Swift markdown libraries don't perform perform well because each elements are rendered as SwiftUI views which introduced a lot of issues So I built my own renderer using TextKit. Even basic things like Settings window is broken. But I still prefer using SwiftUI as It gets the work done faster and I can always fallback to AppKit.
I find that web tech like React are worst than SwiftUI. React also has re-rendering and state management issues
peheje 1 days ago [-]
Despite all the trends, I still really like HTML for structure, CSS for styling, and JavaScript for logic.
The boundaries aren’t perfectly clean, and that’s fine. But the separation gives you a useful way to think: structure this first, style it later, add behaviour where needed.
My experience with Compose—though I suspect SwiftUI people will recognise the feeling—is that I have to think about everything, everywhere, all the time.
Then we add some MVVM/UDF flavour. The "ViewModel" knows nothing about the view, despite usually serving exactly one screen. Add some "MutableStateFlow"s, combine them into "ScreenUiState", expose it as a "StateFlow", collect it with lifecycle awareness.
Beautifully decoupled. Extremely testable.
Then the organisation writes no unit tests and relies entirely on two-hour nightly screen tests.
A welcome-page refactor breaks the profile page.
“Didn’t you check the nightly build?”
No. It runs at night.
“Well, that’s your responsibility.”
But you broke it.
“Yes, but it’s your code.”
Then why did we ship it?
Fine. Schedule the postmortem with my mother.
And I’m not blaming mobile developers here. I’m frontend, backend, full-stack, I think AI engineer now. I have personally helped make simple things complicated across the entire stack.
What I like about the web is that one simple screen can be vanilla JavaScript. Another can use Vue. Another can use some specialised spreadsheet component.
People react to that with horror: what if components are duplicated, behave or look slightly different?
Fair concern. But that is real coupling with visible consequences and trade-offs. Somehow we have started treating coupling as something abstract that only exists inside code, rather than something that should produce an actual benefit when removed.
HTML. CSS. JavaScript. Or something close to it.
Maybe I’m getting old.
leecommamichael 5 hours ago [-]
> I have to think about everything, everywhere, all the time.
I think this is familiarity speaking, which is what you're expressing earlier in the comment anyway. The reality is that we have to think of everything when telling a machine what to do. Exactly how we get that done is preference.
dosisking 17 hours ago [-]
> Despite all the trends, I still really like HTML for structure, CSS for styling, and JavaScript for logic.
I guess I'm even older, because I prefer HTML4, without CSS. And I like using tables for layout instead of divs.
I always hated CSS.
emehex 1 days ago [-]
I've noticed that developers who started with UIKit really have a hard time working with SwiftUI. I think this is because it's not just new syntax, it's an entirely different way to think: state is the source of truth, views are ephemeral, and you describe UI instead of managing it.
CharlesW 1 days ago [-]
> I've noticed that developers who started with UIKit really have a hard time working with SwiftUI.
I think this is true. SwiftUI became "very good" as of iOS 26 (in part because the performance gap mostly evaporated) and continues to get better in iOS 27. Over and over, I see UIKit developers trying to do things "the UIKit way" in SwiftUI, and they'd rather write TFAs instead of considering that they may need to skill up and learn to write effective and idiomatic SwiftUI.
mirsadm 16 hours ago [-]
That's just not true. I am still finding the UI taking 40-50% of CPU time with many hours of wasted time on optimising it and ugly hacks. There's no convincing some people though. Because they can always say you just don't know how to use it.
Well I've been doing this for a pretty long time and I'd like to think I'm pretty good at it.
oefrha 19 hours ago [-]
Now, if only that code you write for iOS 27 can also work on older versions of iOS, instead of having to maintain legacy code for old versions forever…
O-stevns 16 hours ago [-]
It becoming "very good" now is the problem, because it's not backward compatible. So for us developers who are still lingering around supporting those poor iOS 15 (soon 17 thankfully) users, you are stuck with UI acting anywhere between horrendous or not not working at all, to being slightly broken, to working as intended.
jshier 1 days ago [-]
Apple has been adding Observable support to UIKit as well, so it's easier than ever for state to be the source of truth in UIKit too. Anyone writing more than simple UIKit apps has known that for a long time, it's just big a huge pain to actually implement without a lot of custom code or a dependency like RxSwift. If Apple had embraced reactive programming 15 years ago, SwiftUI would be UIKit's new layout system, not a whole new API.
Personally, SwiftUI makes the 80% so much easier that, even if the remaining 20% requires dropping down to UIKit, it's worth it.
frizlab 1 days ago [-]
More or less the same happened with ObjC vs. Swift when it came out, I think.
happytoexplain 19 hours ago [-]
I don't know, in my circles Swift was welcomed like a long-awaited friend. We loved ObjC, but none of the advantages ObjC has over Swift are relevant to app dev. Conversely, everybody recognized the beauty of most early Swift features, notably Optionals.
happytoexplain 20 hours ago [-]
I have always treated state as the source of truth in UIKit. Every view gets an equatable state struct, and mutating it triggers an idempotent view update. Self-mutating views (e.g. inputs) back-propagate their state up the view hierarchy.
SwiftUI/React/etc don't introduce that pattern, they simply enforce it (and add efficiencies).
If a developer isn't familiar with the pattern, it's not because they are a UIKit dev, it's because they are inexperienced.
ajpaulson 17 hours ago [-]
Any chance you have any links so I can read up on this approach?
archagon 1 days ago [-]
It’s also not possible to make super bespoke interfaces without going against the grain of the framework: anathema to old school AppKit and UIKit devs.
cosmic_cheese 18 hours ago [-]
It's not just super bespoke that SwiftUI can't do well, there's lots of little things that are standard in UIKit and AppKit) widgets that inexplicably never made their way over to their SwiftUI counterparts. It's not unusual to have to drop down to the UIKit version for some little thing that Apple couldn't be arsed to port over.
This is incredibly frustrating, particularly now that more UIKit and SwiftUI widgets share underlying implementations.
troupo 8 hours ago [-]
Where "bespoke" is anything beyond master/detail and endless lists upon lists apparently.
lonelyasacloud 12 hours ago [-]
Used SwiftUI mainly on macOS since it was first released.
On macOS it is still comes up short on a lot of the GUI functionality. Stuff like window management, decoration, focus, undo/redo, finder tree type views etc. What Apple have implemented seems okay to me for iPad, iOS etc, but is not up to the standards users' expect for non-trivial native desktop applications.
With enough determination most of the omissions on macOS can be worked around by breaking the SwiftUI encapsulation and delving into AppKit or jarringly inelegant solutions. All of which are somewhat liable to ended up binned when/if Apple pull their fingers out. I had higher expectations of Apple, and overall, it's easy to understand why it does not have a stellar reputation.
As to why it's a bit rubbish on macOS; SwiftUI is largely a mapping to UIKit, AppKit etc primitives. At a guess Apple wants to reduce that number and are seeking to minimise investment in moribund technology.
smallstepforman 7 hours ago [-]
Death by a thousand cuts. First the tech community screamed about memory leaks, so they bolted ARC (automatic resource counting) into Cocoa since unlike C++, Objective-C had no RAII. With swift to be compatible, they forced ARC to all objects. To make RAD (rapid application devolpment), they forced InterfaceBuilder onto the dev community, where artists do layout, but engineers do code. With variable sized screens, RAD tools add constraints to layout, since artists do gui, not engineers. To support Retina displays where GUI is x2, two sets of constraints were added. Spaghetti after twine after hack after crap.
All this goes away if you use a language with RAII, dont treat your devs as morons that cannot manage resources, and allow procedural GUI - let smart dev fix layout and pixels per inch. Artist can create mockup screens in photoshot or after effects, devs do actual procedural coding.
But no, we’ve gone the LEGO assembly way to avoid hiring smart devs.
Disclaimer - I do graphic engines with GUI toolkits for a living.
searls 10 hours ago [-]
I'll be honest, I struggled to get much done with SwiftUI each of the last four years but this summer I started 4 greenfield iOS 27 apps on SwiftUI and it's genuinely been pretty delightful and none have required escape hatches to UIKit/AppKit.
I get people are upset, but the edge cases and frustration in no way feel like fundamental failures—just stuff they haven't gotten around to yet. Yes, they should have gotten to them all sooner but that doesn't convince me they won't eventually.
flenserboy 8 hours ago [-]
there's yet to be a decent-looking SwiftUI app on the desktop. elements are always too small, spacing is wrong, & the keyboard is a second-class citizen. mobile-first is a disaster.
There are still a lot of rough edges when it comes to look and feel on Apple platforms but it gives me the performance and speed while also being multiplatform.
happytoexplain 1 days ago [-]
Autolayout, while flawed like anything else, remains the pinnacle of UI across all platforms.
SwiftUI is a laudable attempt to idiot-proof UI, but it sacrifices too much and ultimately fails.
Klonoar 10 hours ago [-]
Every time I have to structure UI anywhere else, I lament not having AutoLayout.
frizlab 1 days ago [-]
I love Auto-Layout so much.
sunnybeetroot 1 days ago [-]
Make 320pt frame layouts great again
/s
frizlab 1 days ago [-]
That’s the point of Auto-Layout, to be able to be responsive…
sunnybeetroot 1 days ago [-]
I edited the comment with /s to make it more obvious that I was joking
dep_b 7 hours ago [-]
The odd thing is that UIKit can easily be transformed into a much more pleasant experience if you just fix some of the worst API’s, like embedding ViewControllers and adding constraints in code.
dzonga 10 hours ago [-]
my take is apple should've hired or worked more with external partners in terms of handling swift.
1. the language had all the right hook points to replace python - but then it was closed off in the apple ecosystem for a while. then it was made to be complex as C++ as time went on. if Swift had remained as simple as Go - and Apple had made a push for swift to go beyond apps in their ecosystem the language for data/ml would be swift
2. in regards to swiftUI - almost the same point as 1. react native took over cz it was a simpler more open ecosystem. then eventually most people stopped bothering with native apps (they're used to track you) - web apps are equally good. hence for most people they use native apps for maps, banking.
willtemperley 14 hours ago [-]
I would only take this article seriously if you have to support old iOS versions.
NavigationStack has been around since iOS 16, @Observable since iOS 17. and I'm not sure if the author is aware that GeometryReader hasn't been necessary since iOS 18 added onGeometryChange modifiers. Nearly 100% of users are on iOS 16+.
I'm doing some fairly complex work with SwiftUI and I find most components work identically between iPad and macOS. I can work for a week without needing to test on an iPad.
There are problems with SwiftUI for sure: I'm finding macOS performance on an M2 Max is far worse than an iPad M1, especially with animations. Toolbars are very inconsistent between platforms and the compiler timeouts are a real pain (hopefully Swift 6.4 will fix that).
viktorcode 13 hours ago [-]
> I'm not sure if the author is aware that GeometryReader hasn't been necessary since iOS 18 added onGeometryChange modifiers.
I think the author does not understand how and why to use GeometryReader at all. He literally said "you find yourself wrapping everything in a GeometryReader" which is a different thing from simply measuring. For measuring you could always put GeometryReader into `.background()` and use that to avoid messing with the view layout. Also, "wrapping everything" is a good sign you are doing something wrong.
Edit: by the way compiler timeouts are not a SwiftUI issue: it is a Swift issue. You can create a timeout situation in pure Swift. For SwiftUI specifically this situation is addressed in the upcoming OS27 SDK.
happytoexplain 5 minutes ago [-]
Compiler timeouts are only a Swift issue because it is so flexible. They don't happen outside of SwiftUI except in toy examples that look simple but aren't realistic. SwiftUI is the only realistic example where timeouts happen (which is unacceptable).
Regarding GeometryReader: Just read your comment out loud.
19 hours ago [-]
23 hours ago [-]
mpfh 17 hours ago [-]
Any modern-day Windows developers want to chime in around WinRT and other stuff Microsoft has been up to? I’m still on Win32 and WinForms.
happytoexplain 4 minutes ago [-]
They are simply not relevant at this level of discussion.
emehex 1 days ago [-]
> real, production-grade UI framework
What does this even mean? There are hundreds of thousands of apps in the App Store that are 100% SwiftUI. They are real. And they are very much "production grade".
The only people still complaining about SwiftUI 7 years later are the UIKit holdouts that never took the time to properly learn how to use it.
brailsafe 1 days ago [-]
> There are hundreds of thousands of apps in the App Store that are 100% SwiftUI. They are real. And they are very much "production grade"
The first is a statement of quantity, the second is a statement of quality, dubiously supprted by the first.
The Mac Settings app still lags between panes years after it was redesigned to look like iOS. I would think that if they had a viable way build a high quality and performant app with even relatively basic UI components (if they cared to do so) they'd do it for the 1 app that's deployed to every mac.
SwiftUI does work in certain circumstances, and does work for allowing people to shit out their ideas faster, but it has struggled with the aspects described in the video. Some companies don't care either, and turnaround time is paramount, but in this discussion it's about quality compared to what came before.
saagarjha 10 hours ago [-]
Settings lags not because of SwiftUI but because it renders all the panes out of process
ChrisMarshallNY 10 hours ago [-]
I liked the promise, but the reality has been disappointing.
SwiftUI is great for test harnesses and admin utilities, but I won't use it for shipping software. I have one app that I rewrote in SwiftUI, just so that I can say that I have shipped it, but I am still using UIKit for most of my apps.
I'm not thrilled with UIKit, but SwiftUI has kind of withered on the vine.
ardit33 1 days ago [-]
SwiftUI it is the type of framework that makes the easy things easier to accomplish but the harder things harder.
It is a newbie trap. It is great at producing simple apps, or things that don't require intense scrolling, or anything with heavy animations and precise layouts, but when you do something smooth, it is not it. It feels more of a React Native competitor, than a true UIKit replacement.
Also, almost everything that Apple has re-wrote with SwiftUI, came out worse as before (Settings, Spotlight, etc), and that doesn't help.
With AI coding... SwiftUI lost its edge/advantage (easy to layout screens), as now you code less of that directly, and might as well just go fo the framework that allows the most flexibility and gives you the best results for your users.
Apple really needs to either double down on it, and make it such that it has everything that UIKit has (match both features and performance), or just turn it into another optional framework, just as Interface Builder (.xib files) back in the day of Objective-C.
Right now it heavily promotes it as a first class citizen, meanwhile the features are not even parity with UIKit. It is so misleading to newcomers to the platform.
Ps. The other upsetting thing about SwiftUI, is that it has hurt the Swift language as well, as the team has had to introduce all kinds of hacks, or obscure features to the language in order to make it work, which made even the Swift language experience worse and more complicated than it should have been.
Razengan 1 days ago [-]
> With AI coding... SwiftUI lost its edge/advantage
On the contrary, I think AI has made it EASIER to approach SwiftUI now, because AI makes up for SwiftUI's biggest weaknesses: the many ways of doing everything, Apple's wonky documentation and the need to know when to fall back to AppKit/UIKit.
ardit33 1 days ago [-]
Maybe for you. But SwiftUI promise was to make coding UI easier for the programmer similar to ReactN, but with AI coding that is not necessary anymore, you can go straight to UIKit which is most stable and feature complete.
In car terms:
UIKit - Manual Transmission - you control everything, but a bit of a chore
SwiftUI - Slushbox Auto Transmission - easier to drive, sucks for performance
UIKIT+AI Coding - Dual Clutch Transmission - both great performance, and easy to control/drive
pupppet 1 days ago [-]
If you’re just getting AI to build you an iOS app, is there any reason to use SwiftUI over UIKit?
dagmx 1 days ago [-]
Yes because SwiftUI is way more self contained and minimally verbose, it’s a better fit for LLM use than AppKit/UIKit
saagarjha 10 hours ago [-]
Yes, because SwiftUI is (really!) the best way to build new apps for iOS. Your AI can probably figure out when it needs UIKit to do what it wants.
wahnfrieden 18 hours ago [-]
Some new platform capabilities are only available in SwiftUI. But you can wrap that for use in UIKit.
sampton 1 days ago [-]
SwiftUI is gold compared to SwiftData.
myko 19 hours ago [-]
To be fair CoreData was always a footgun as well
emehex 1 days ago [-]
Agreed. SwiftData is terrible for anything more than like 2 "Models". I have a bunch of apps written with SwiftData and a bunch more with GRDB... I hate touching the SwiftData ones.
ardit33 15 hours ago [-]
SwiftData is just a framework that you can choose to ignore and not use at all. Even CoreData.
You can go straight to the source, and use some small layer on top of SQLite, and ignore that noise (most large apps just do that).
But, SwiftUI is being pushed as the way to do UI, and as a replacement for UIKIt/the future of apple, where it is not even near feature parity with it. That's the most troubling part of it.
I wished apple just made it as a Template Rendering framework, and integrated wit with UIKit, and just modernized UIKit a bit.
wahnfrieden 18 hours ago [-]
SQLiteData is the winner.
the-golden-one 1 days ago [-]
A similar story to WPF.
tonyedgecombe 1 days ago [-]
WPF was abandoned at birth, it went years without any attention and then was superseded.
Apple has at least been consistent on UI frameworks.
dgellow 1 days ago [-]
Sort of superseded. In practice WPF is still very often the best option in the complete mess that is window GUIs
masfuerte 1 days ago [-]
Yeah, I like WPF and I still use it for my own apps. In fact, my own software is the only thing keeping me on Windows now. I really should take a look at Avalonia and port my stuff over to Linux.
VCFundedGenYer 1 days ago [-]
I think you might have meant UWP.
WPF is still around and have been spruced up as of late.
UWP was the DOA Windows 8/8.1/10 app format that was super restrictive, strange to develop for, and non-portable. It's basically MS's equivalent of SwiftUI.
Razengan 1 days ago [-]
WPF was stamped out by lack of dogfooding = inability to inspire confidence, and then Microsoft spazzing out with that clusterfuck that was the Windows 8 "Metro" bullshit.
Back when I wanted WPF to succeed, Microsoft was barely using it in any of their own apps.
Apple has used SwiftUI in their OS more than MS/Windows did, and there's quite a few apps on the App Store that -seem- to be made with SwiftUI.
zombot 17 hours ago [-]
You know those games you buy as Early Access while they're still in development, with the implied promise that development will be done some day? And how many of those games have stayed Early Access over so many years that you stopped believing they will ever be done? That's SwiftUI. I won't touch it.
interpol_p 18 hours ago [-]
SwiftUI has a lot of failings, but it can also do a lot of things that are really tricky in UIKit.
I can render Metal shaders trivially in SwiftUI. Rendering glows, and blurs, and animated effects is much easier in SwiftUI than in UIKit, just use `.blur(radius:)` or `.blendMode(...)`
I have used AppKit and then UIKit since its inception. Creating visual effects like layer masks that modulate the opacity of underlying views is trivially easy in SwiftUI — far easier than the boilerplate and constant bookkeeping that CALayer's mask requires.
So a lot of the advanced full-screen animations in some of my games and apps are SwiftUI, because they are performant, provide the cool effects and animations, and work great. A lot of the simple get-the-job-done views and tool palettes in my apps are also SwiftUI, again because they don't ask much and get the job done, and look great.
However, where SwiftUI falls down is exactly what was demoed in the video: large collections of thumbnails that fetch asynchronously? Use UIKit. Multi-thousands of items in large, complicated lists? You can try SwiftUI, but you'll need to learn how to optimize it.
Other things, not mentioned in the video, that are more annoying in SwiftUI: want to take control of a transition between views, end-to-end? Not really possible in SwiftUI. There are bugs with ZoomNavigationTransition that affect all of Apple's own apps, and you aren't gonna be able to fix them without switching to UIKit.
vintagedave 4 hours ago [-]
But just imagine if they'd spent this time making them easy in UIKit.
saagarjha 10 hours ago [-]
SwiftUI has a bunch of problems but almost none of them have anything to do with what this guy has to say :( Like, there are issues with almost every point:
> We started with @State, @Binding, and ObservedObjects. Then Apple realized the performance was disastrous and SwiftUI was re-rendering views all the time. That’s when it introduced the Observation framework and the @Observable macro. They tried to solve the problem with compiler tricks, but it clearly wasn’t enough so the layout engine continued its guessing games.
Not why @Observable was introduced
> In SwiftUI, you can never know for sure how many times a view will update and, when it does, why it chose to.
Instruments tells you these days
> That demo project from the SwiftUI tutorial has a very standard, non-custom one. You build the project with the latest Xcode and launch the app on the latest macOS—only to get this.
Yeah, it's a demo marked as "this is old, please do not use it"?
> What is a SwiftUI problem is the overall fragility of UI layouts. They fall apart in the most unexpected ways and at the most unfortunate moments. You can see it in the very real, production apps like UTM. It’s a fantastic piece of engineering, but its reliance on SwiftUI sometimes makes it feel like an early prototype.
This is an app written by someone who spends most of their time writing graphics APIs I think the fact that they can do something half-decent is really a testament to how approachable SwiftUI is
> In the end, you find yourself wrapping everything in a GeometryReader. And this is the ultimate admission of defeat.
No I only use GeometryReader when I actually want to do some coordinate math
> Okay, maybe you want to let your users customize the window toolbar, just as they could since 2001 (or something like that). Well, SwiftUI received this “breakthrough” feature only a few years ago.
iOS 14 my guy, this is literally one year after SwiftUI was released
> And then there’s the most basic task: displaying images you fetched from the network. Well, you better write your own fetcher, because AsyncImage was introduced only in iOS 15.
Can you point me at the API in UIKit that lets you do this?
> But if you want to also cache those images, I’ve got bad news for you: You can’t do it at all because right now, in July 2026, this API is still in beta.
Or this?
> For all these scenarios, developers usually come up with their own hacks and workarounds.
Yeah, it's called "you download one of a handful of libraries to do it for you". Now you don't have to do that.
blkhp19 4 hours ago [-]
This should be the highest-rated comment. The guy who posted this video / transcript is wrong about so many things - I'm actually convinced he's being purposely misleading. It's an opinion about SwiftUI backed up by misleading and inaccurate claims.
Razengan 1 days ago [-]
I fell in love with SwiftUI the day it was announced, but as a solo dev I still haven't been able to make a full app with it yet, mostly because of the lack of documentation, and the gaps where you still need to drop down to AppKit/UIKit.
I went through Visual Basic, .NET, WPF, Cocoa, and other random frameworks all professing to be the promised panacea for UI, but I think SwiftUI+SwiftData is the best environment ever.. IF only it could reach its full potential, i.e. do everything that Apple's "legacy" APIs can do.
The biggest/worst hurdle in the "modern" dev experience is Apple's insistence on a yearly update cycle and the way they advertise those updates: You have to wait for the next WWDC and suffer through videos of uncanny-valley presenters, hoping to catch a glimpse of something that fixes the shit that was bothering you since the last WWDC.
3rd-party sites like hackingwithswift.com & swiftwithmajid.com provide invaluable info that Apple's own docs should.
At least the Swift language has been getting more regular updates since it went open source.
There's no way I'd dare to take on a full Apple-platform app project alone on my own, but I've started dabbling in it again thanks to AI: Codex even converted an old app I made in Visual Basic 900 years ago and had it running in SwiftUI within minutes!
I've even tried to get AI to sift through the WWDC video transcripts so I won't have to waste my mortal lifespan on that.
zer0x4d 1 days ago [-]
Yeah I don't really understand their insistence on these videos. I don't have the time to watch an incredibly hard to watch present babywalk me through the code, hoping I'd catch one modifier I missed that fixes the issue. Just write some docs for god's sake.
sunnybeetroot 1 days ago [-]
They update the docs every year. The videos are for people who want a demonstration instead of reading docs and trying things manually to see the result.
zer0x4d 7 hours ago [-]
There are lots of detail in the videos that are never mentioned in docs
CharlesW 1 days ago [-]
> There's no way I'd dare to take on a full Apple-platform app project alone on my own, but I've started dabbling in it again thanks to AI: Codex even converted an old app I made in Visual Basic 900 years ago and had it running in SwiftUI within minutes!
You may like my project https://charleswiltgen.github.io/Axiom/ (FOSS). I was in the same place a year ago, and initially created Axiom as a private skills suite before deciding that it was too helpful not to share.
steve1977 1 days ago [-]
> There's no way I'd dare to take on a full Apple-platform app project alone on my own
And that's really sad, because earlier Mac OS X (and even OPENSTEP to a degree) was an Eldorado for boutique developers, not least due to frameworks like Cocoa and Objective-C (despite all the hate it seems to get).
If you knew C, it was not hard to grasp Objective-C (at least it was much easier than say C++ and MFC on the Windows side of things).
Razengan 1 days ago [-]
That's actually why I jumped from Windows to Mac in the first place!
My first Apple purchase was an iPad I got for my aunt, and I loved how streamlined yet powerful it was so I installed a VM on Windows to dabble in iOS development, and fell in love with the sheer consistency of macOS, iOS and their APIs.
This was during the era when Microsoft was still figuring out whether to keep the Start Menu and replace the whole Windows UX with a tablet UI, so it was an easy jump.
Almost never looked back, and whenever I do I'm glad I jumped.
Then came Swift and I loved it, but then it took literal years to catch up with everything you could do in Objective-C with the Apple APIs. SwiftUI is having the same problem but for much longer :(
viktorcode 15 hours ago [-]
> Then came Swift and I loved it, but then it took literal years to catch up with everything you could do in Objective-C with the Apple APIs.
I don't get this part. You can literally rewrite Obj-C code verbatim in Swift and it will work. The only missing part is C macros.
Razengan 12 hours ago [-]
> You can literally rewrite Obj-C code verbatim in Swift and it will work.
It took a while to get there. They didn't have native Swift APIs for some things like URIs etc until later.
Razengan 15 hours ago [-]
P.S. Re: AI, I don't mean outright generating entire apps from a single sentence (except for conversions of private tools), but using AI to navigate Apple's obtuse documentation and edge-case APIs, i.e. "how to do this"
formvoltron 1 days ago [-]
Is the right way to develop mobile apps flutter? or Kotlin multiplatform plus native UIs?
palata 1 days ago [-]
What I like about Kotlin Multiplatform (KMP) vs Flutter is that KMP is not a framework. For instance, I can write a KMP library and a "pure" Android or iOS app can pretend it is a "pure" Android/iOS library.
That is, pure native apps, can integrate KMP libraries. They cannot integrate Flutter libraries.
In other words, if I write a KMP library, I can ship it for multiple platforms and developers can use it in their Flutter project, or in their pure Android/Kotlin project, or in their pure iOS project.
rubymamis 1 days ago [-]
I know people would dismiss this, but I'm going to try to make the case for Qt - I'm currently converting my note-taking app to mobile and it's going very well.
afidrya 1 days ago [-]
It's licensing is expensive though unless the app is opensource.
gen2brain 1 days ago [-]
I heard this repeated many times. You can create closed-source Qt apps without paying any money. You cannot statically link, though; you must obey the LGPL license; that is all.
And yes, you cannot use commercial modules, but that is kinda expected.
preg_match 1 days ago [-]
Yes, Qt is mature and high-quality software. If you’re doing OSS, then Qt is truly a no brainer. The amount of C++ you have to write is truly minimal, and it’s not “raw” C++. There’s a lot of tooling and libraries. You can target web now too, and QML is legitimately good.
If KDE can develop a high performance stable desktop, you can design whatever.
palata 1 days ago [-]
I have been involved in two non-trivial Qt mobile apps. Never again.
I don't know what your experience is, and I mean no offence or anything, but the only people I have seen who were happy with Qt for mobile development were people who had never tried to do it with a modern language, like Kotlin.
With Compose Multiplatform and Kotlin Multiplatform, you can write a cross-platform app in a modern language, and that is far better than C++.
danscan 1 days ago [-]
There is no right way :)
SwiftUI is good, albeit not without issues, as long as you tolerate them. The same is true for any approach. My most recent app was built in SwiftUI because I have been using React Native in my professional work for so long I wanted a change of scenery.
Each approach has its issues, and it all boils down to a matter of preference and which tradeoffs are appropriate for the project.
rumori 1 days ago [-]
I’ve worked on some award winning apps in the past, our experience with SwiftUI is it makes it really easy to develop a basic average looking app. As soon as you need something non-standard, you have to drop down to UIKit and figure out how to play nice between the two, which is often non trivial and hard to estimate. You file radars, which at best will be fixed in the next OS release and rarely back ported if at all.
In the end some of the more complicated apps just ditched SwiftUI altogether or applied a myriad of workarounds.
ducktective 1 days ago [-]
I wonder what experts think of this other option: going fully native for one platform then vibe-porting it to others.
palata 1 days ago [-]
It's never "just working", you'll still have to debug the vibe-ported apps. And you won't be good at it if your devs don't actually know the target platform.
All that to say, I don't think that vibe-porting will give you more than cross-platform. With cross-platform, at least your engineers understand the codebase.
krzyzanowskim 1 days ago [-]
Flutter is not the "right way", due to the nature of Flutter being a lousy reimplementation of a UI frameworks.
randyrand 1 days ago [-]
I developed a complicated app in Flutter and it’s one of the best engineering decisions I made. Flutter is great.
livinglist 1 days ago [-]
Define right, it’s hard to replicate the native UI especially Liquid Glass on iOS because it’s rendering everything using its own rendering engine, making it hard to feel right on iOS. I have also seen a lot of companies move away from flutter to either native or React Native.
lowbloodsugar 1 days ago [-]
Well we all love Liquid Glass. Most loved UX update in iPhone and macOS history. Massive dealbreaker for an app not to look like Liquid Glass. I definitely choose apps based on whether they look like proper Liquid Glass applications instead of the developer taking shortcuts and focusing on working features instead.
lelandfe 1 days ago [-]
You jest but yes, even as I do not love this new update, an application bucking Apple platform standards personally sours me pretty hard on it.
livinglist 1 days ago [-]
Well I’m a heavy Flutter user myself, and the app I built Hacki often gets reviews saying it doesn’t feel native on iOS. I personally don’t have anything against it and I think Flutter has the BEST developer experience compared to other mobile app dev toolkit/SDKs.
afavour 1 days ago [-]
I despise Liquid Glass too but for most users there’s a broad feeling of “it fits” vs doesn’t. And apps with Liquid Glass fit today’s iOS.
frizlab 1 days ago [-]
Neither.
SV_BubbleTime 1 days ago [-]
Flutter has been a great success for us.
rumori 1 days ago [-]
Same here, but Liquid Glass has been a headache lately. Google really dropped the ball here, but to their credit it almost feels like Liquid Glass was an intentional move by Apple to cause as much friction for cross platform frameworks as possible.
zer0x4d 1 days ago [-]
SwiftUI was doomed from the beginning. Not only Apple completely blew the implementation, it was actually DoA by a bunch of super bad decisions that ultimately make it incredibly hard to work with and manage, especially on bigger apps.
1. It uses the builder pattern for views (familiar to those who used Java) but for some reason they decided to make it so that the order of the modifiers in the builder matters. Each modifier doesn't actually modify the main view but it modifies what the modifier before it decided to return. This makes no sense as the modifiers should each be modifying the main view to make everything predictable and easy to debug. I'm convinced no one (not even senior devs with 5 years of SwiftUI experience) understands how the ordering of modifiers works. It's just swap them until it does what you want it to.
2. The view lifecycles and code execution path seem random and hidden behind layers of "magic," making it incredibly difficult for developers to trace and debug issues.
3. It is practically impossible to set breakpoints for rendering and view construction, it's impossible to really figure out when re-renders happen and what drives them. I'm convinced SwiftUI apps are incredibly slow not because the SwiftUI implementation itself is slow, it's because, even Apple's own apps probably do a bunch of unnecessary re-renders and one no one seems to have any idea. This is unfortunately another design issue that can't be solved by just making SwiftUI more efficient. It requires simplification and tooling to help developers not footgun themselves.
4. Lots of issues start appearing later on in the development cycle because, for simple apps, bad SwiftUI design decisions and footguns have unnoticeable effects, until the apps gets more complex and things start breaking. Fixing these issues sometimes requires rewriting whole features or spending hours debugging.
5. There seems to be almost no documentation on Liquid Glass. It's laughable that after more than 1 year, Apple has simply refused to document or provide good examples for Liquid Glass, except for maybe couple pages that resemble the brain dump of an engineer that has never passed a writing class in college?
6. Stuff seems to be rapidly changing and breaking from version to version. It took days to make my app look and work the same in iOS 27 as it did on iOS 26, even though iOS 27 is supposed to be a minor bug fix release. We don't even use anything non-standard and don't do any hacks. This defeats the whole purpose of a simple UI framework that can be easily adopted to different platforms (this never used to happen with UIKit).
7. View debugger still has no SwiftUI equivalent. It used to make things so much simpler in UIKit when you could just see the view bounds, pick views apart and understand what's actually happening. SwiftUI has no equivalent other than `.background(.red)`. Terrible.
I don't know how Apple can salvage this beyond just undoing some of these terrible design decisions and making it 1. super simple to work with, 2. stop relying on magic, making things more explicit, and 3. providing actual 1:1 UIKit feature parity.
jshier 1 days ago [-]
1. It's not really the builder pattern, which, in Java, is what you describe as wanting: mutating a single instance. SwiftUI uses result builders to compute a single generic View from the "DSL", but you could do the same thing without the custom syntax, it would just be more verbose.
2. Documentation issue. The lifecycle is standardized, but Apple is terrible as documenting it all in one place. I found this year's "Dive into lazy stacks and scrolling with SwiftUI" WWDC video actually had a pretty good explanation, at least for the lifecycle within lazy containers.
3 and 7. Yes, Apple's tools suck pretty bad. Preview canvas is also still terrible, despite multiple attempts to improve.
4. Not something I've experienced, not sure what you mean.
5. Yeah, Apple's docs suck.
6. Not sure what you mean here either, our stuff looks pretty much the same.
palata 1 days ago [-]
Apple seems to be loved by users, but hated by developers (and for good reasons). They just seem to not give a shit about the developer experience.
You mention some examples, I have experience with lower-level stuff: terrible. Poorly documented, and actually not really working well.
IMO they should focus on improving the developer experience instead of wasting money on the joke that is Liquid Glass (even users don't like it, right?). But anyway, too late for me: I'm soooo happy that I can develop iOS apps in Kotlin now, and just endure Xcode for building and occasional debugging.
a34729t 18 hours ago [-]
They used to care about developers. Peak cocoa and uikit was a thing of beauty and objc remains my favorite programming language of all time. When Swift came along i tried and was dissapointed and then a decade later i gave it another whirl and was shocked it was still so bad. The hardware has gotten better, but the software clearly not.
mpweiher 1 days ago [-]
This used to be different. NeXTstep and early MacOS-X were pretty much the finest platforms to develop on.
steve1977 2 hours ago [-]
And they had great documentation
sandoze 1 days ago [-]
Just a couple points because your opinions aren’t wrong, they’re just your lived experience.
2. There’s no magic here. There is poor documentation. The biggest trick — small views, think about what values are going to trigger a refresh. Avoid cascading view refreshes.
6. You might have missed a couple big iOS releases (iOS 7 was one to remember) where many of our apps fell over in UIKit. Swift was another ‘DOA’ for YEARS with the same issues you’re making here, each new version broke the old, but here we are in a day and age where it’s the standard.
zer0x4d 7 hours ago [-]
The magic is when you use things like @State or @Published and system does bunch of things hidden behind the scenes that the developer has no idea about. Then, when issues arise, the developer is unable to debug because they have no idea how these things work and what they really do.
fenestella 19 hours ago [-]
[flagged]
slopinthebag 19 hours ago [-]
[flagged]
migueldeicaza 1 days ago [-]
skills issue
migueldeicaza 1 days ago [-]
I joked, but reading the post is even more clear - man this poor dude.
He is brute forcing his way through life and broadcasting it on YouTube.
Dunno man, Xogot is made up of almost half a million lines of code. Of those 727 files use SwiftUI, and 65 use UIKit, 119 use AppKit (I did not count the overlap, so they are not mutually exclusive).
Using GeometryReader makes it clear he is living in the past and the fact that he uses printChanges in this year without mentioning the dedicated SwiftUI instrument show a lack of curiosity on the space.
miffy900 16 hours ago [-]
So in other words you have no response to any of the arguments in the link? just some silly ad-hominem attack on the author. right.
vintagedave 12 hours ago [-]
> Using GeometryReader makes it clear he is living in the past
He seems to phrase it as though he has to, that he falls back because nothing else works. What would you suggest instead?
I'm only lightly familiar with both Cocoa and SwiftUI, but I have heard many nightmare stories about SwiftUI and Swift the language. I'm inclined to take his criticism seriously, and I think there's a big distinction between people who know a platform very deeply -- you are a strong expert almost everywhere you touch :) and it's clear from your comment SwiftUI works for you -- and normal developers who, you know, just want to learn a framework once and use it to get a job done. Living in the past is not necessarily bad; it's a good thing if what worked in the past worked well and still works today.
lysace 1 days ago [-]
Somehow you being the GNOME co-creator made me curious about what the GTK/GIMP creators (Kimball, Mattis) are up to. CockroachDB, it seems. It's weird how it's so easy to miss these connections.
migueldeicaza 1 days ago [-]
yeah, I often check on them - love watching what they are up to.
Let me rephrase, he is not the sharpest knife in the drawer.
In my professional medical opinion, he is at high risk of being replaced by a year old low-end Chinese open source LLM.
palata 1 days ago [-]
Maybe unrelated, but as an Android dev, a few years ago I wanted to look into SwiftUI.
But now I feel like for most apps, I should be fine with Compose Multiplatform and Kotlin Multiplatform. I don't see the point of learning SwiftUI anymore.
frizlab 1 days ago [-]
Well you could do android apps using SwiftUI ¯\_(ツ)_/¯
palata 13 hours ago [-]
But then I would have to endure the Apple developer experience...
frizlab 9 hours ago [-]
To each his own, but I actually like it
harrouet 15 hours ago [-]
Agreed that SwiftUI because bloated and hacky, when it promised simplification and transparency.
But is there a single UI abstraction that succeeded in affordability for newcomers while maintaining performance and solid architecture?
It is high time to solve the write-3-apps for each usecase (iOS, Android, Windows). I use MAUI on some projects but it is still not perfect.
The way forward for Apple is to open source more and more and let the Swift community build a cross-platform solution.
Apple's inability to deploy a new UI framework that's better than the previous one is troubling. This is the company that shifted from Toolbox to Carbon to Cocoa and each step was better than the last. Could Apple build MacOS X and Cocoa today if they didn't already exist? Microsoft's two decades of failure to ship a true successor to Win32 suggests that Microsoft (at least, the operating system side of the company) died a long time ago. I wonder if we'll say the same thing about Apple 10 years hence.
This isn't 7 years of development, but 7 - 12 years after release. And to most these past 7 - 12 years are an ongoing beta development. It is unfinished, unpolished with no end in sight. And I have been extremely critical since the beginning.
But the problem runs much much deeper. It isn't the technology that is the problem, not the devs who are making it. It is the person making the decision as to WHY this was allowed from the get go. WHY this was allowed to be released, or even before all that WHY resources for development of these ideas were allowed in the first place.
For every yes that are a thousand no. Instead a lot of Apple's software development can be summarised as resume or KPI bonus driven development. It is not as bad as Google and Microsoft, but it is clear Apple have this problem a well.
If you look back into Jobs era of Apple software, ( and not just software ) Apple manage to have done most things 2x better with half the resources. The whole Apple now is bloated. And yet everyone is chanting Craig Federighi all the way.
And it is funny because for the vast majority of these 7-12 years I was the only few on HN and Twitter that was extremely skeptical of it, to the point I gave up writing ( or ranting ) about it before majority Swift and Swift UI developers negative sentiment emerged.
And I have often asked the same question every single time, what if they just spend one fifth of the resources to iterate and improve C / Objective-C and Cocoa. All the resources on Swift and everything adjacent to it could have been better spent somewhere else.
I have high hope for John Ternus, hopefully he gets his political game right and manage to change course for Apple software somewhere down the line.
When did the term “KPI” come into use at Apple? I’m aware it was used in management circles decades ago but I don’t remember it being so common say in 2005. The underlying concept is sound, but the problem with abstracting it under an acronym is that it treats KPIs as somewhat fungible regardless of importance. It’s like “lines of code” as a productivity measure all over again.
What were the emerging problems that you talk about? I am actually curious because I was quite fond of the DevEx
it would have been a great language, meanwhile they decided to throw everything out and created a language that it is overcomplex, and it is failing to gain any traction outside iOS / Apple's ecosystem. Basically, if you weren't required to use it, nobody would, which makes it a failure.
SwiftUI, should have been a rendering template/library integrated with UIKit. Also, cleaning up some of the UIKit syntanx and framework (simplifying it), and use SwiftUI as a template for UI, would have been ideal.
SwiftUI instead was pitched as replacement, yet it is not near as capable as UIKit, and it is not feature parity even 7 years later.
Just bad leadership by Apple in this case. (probably many of these decissions were 'promo / resume padding driven' as it happens in many large companies).
> "We need to be true to ourselves, and remember what is important, that is what going to keep Apple Apple, is if we keep us, us."
> "You have got to start with the customers experience and work backwards to the technology.
Right now it feels a lot like Apple without Steve Jobs the first time round. On paper there are a lot of cool tech being worked on. But in the end it was tech from NeXT that really shines.
And a lot of these tech don't actually benefits the customers. If the choice was a language and framework that is slightly harder to developers but brings overall higher quality Apps because the barrier is higher. Compared to a language that wants to replace Assembly to Javascript while being easy to learn like Visual Basic and for everyone to code. I would much rather pick the former.
Edit: I suddenly remember I also submitted a Core Animation introduction video from Steve a while ago on HN [1]. 20 years later we have gone backwards on a lot of things.
[1] https://x.com/lucaslovexoxo/status/2082098579632783441
There’s no way Apple doesn’t know about that internally. So I don’t see any other explanation… other than a lack of care, or a bozo explosion.
And if you dont have it already… then what could I possibly say that would motivate you to buy a used one to do the testing to confirm?
Edit: And even on my ipad pro m2 doing literally nothing other than swiping to the app library often causes a visible stutter and lag for hundreds of miliseconds… so if you really think it’s flat out impossible to find consistently slower things on the much more complex macos… idk what to say.
And your iPad example doesn't make sense at all, you compared 2 Macbooks and now you're talking about another OS altogether.
> idk what to say.
You could just tell us one example of something that's faster on your 2019 Macbook Pro 15 versus a M5 Macbook pro and how to reproduce it.
Which means Objective-C was a failure, right?
That's what Objective-Smalltalk is, or rather, what it started out as.
https://blog.metaobject.com/2019/12/the-4-stages-of-objectiv...
It has now gone further to actually implement Brad Cox's idea of a "Software IC", by taking on ideas from software architecture and metaobject protocols.
https://2024.splashcon.org/details/splash-2024-Onward-papers...
> SwiftUI, should have been a rendering template/library integrated with UIKit.
Do you mean it should have used some sort of XML-ish/HTML-ish templating mechanism? For Interscript, I keep looking at that approach, but so far haven't gone down that road (except for HTMXNative, but there it actually is HTML, so...).
The number one archiac/weird thing was message passing instead of methods. Number two was square brackets for message passing.
What would be left of Objective-C once these were left behind?
> and it is failing to gain any traction outside iOS / Apple's ecosystem.
Objective-C was on a path to gain serious traction outside of the Apple ecosystem?
Rescued by NeXT's acquisition, having failed to gain market adoption otherwise.
But I feel like Apple wanted to appeal to young web devs and tried to offer something more similar to what these are used to.
I sure hope they can figure out a way through. Whatever it is, SwiftUI isn't it.
I think this opinion is heavily shared by Swift developers now, but the messaging every WWDC is always "Swift and SwiftUI is the best way to build apps for Apple Platforms", etc.. If you have to keep telling everyone what they don't believe is true, it's a sign there's a problem.
It feels like someone with a lot of organizational power is disconnected from the pulse of the community. SwiftUI is undeniably clean in a lot of ways, it presents beautifully and fits on slides well, but that matters less and less, and this all wasn't really working out even before LLMs disrupted things.
But they do quietly drop or fix them, covertly acknowledging they were mistakes. Often with this messaging: "we have this new shiny thing that is even better than the old shiny thing (that was really a turd)".
Remember "garbage collection"? Or "modern syntax"? Or CocoaJava?
And with hardware they had their "come to Jesus" moment a while ago. And then hit it out of the ballpark with Apple Silicon.
The one for software is still upcoming.
But I also really liked Objective-C.
Classic iPhone apps have fixed layouts, and classic Mac apps have a big dynamic document in the centre with mostly fixed toolbars around the sides, and dialogs with fixed layouts. Making a really dynamic layout with OS widgets is a huge pain, so most apps sidestepped it.
As Apple gradually added more and more slightly different sizes of iPhone and iPad, making good UI layouts got harder. Even handling screen rotations is a huge hassle! If iOS had proper support for resizing from the start, screen rotation would be trivial, just another window resize.
Xcode had Interface Builder and autolayout, but I found those to be disastrously fiddly and unusable. Maybe some people like them?
HTML has many problems of its own, but it does have good support for responsive layouts. CSS isn't perfect, but it's vastly better than anything you can find in macOS, iOS, Android or Windows.
It seems to me that SwiftUI was trying to tackle two problems at once: React-style declarative UI, and responsive layout. Those are both good ideas, but trying to tackle both in a single uber-framework and deprecating the lower layers was too ambitious. As somebody said elsewhere in this thread, SwiftUI could have been decent as just an optional helper on top of the existing UIKit / AppKit.
I get their appeal (in the sense of only having to develop one layout), but IMHO, in many cases more strict layouts would be the better choice.
You mention classic apps having a fixed layout, I think that's a good thing.
Not every user interfaces makes sense in portrait AND landscape mode for example.
And the slightly different sizes of iPhones are not really that problematic with something like autolayout.
But I don't think you can cover all requirements with a set of fixed layouts, they do need to be somewhat flexible. Even if all screens were the same size, you'd want to be able to boost the font size for accessibility, and that essentially means scaling the whole UI.
And the slightly different sizes of iPhones are not really that problematic with something like autolayout.
I think something like flexbox is a better fit. There are tradeoffs in each approach, but I usually find a local, modular, bottom-up approach easier to work with than global constraint solving, even though it seems in principle like it should be nice to be able to say "keep this button here in relation to this other button". As you add more constraints like that your layout slowly turns to mush and doesn't actually resize nicely. (Edit to add: I'm probably conflating a few different generations of iOS toolkits here, I realise autolayout is somewhat separate from constraint-based layouts.)
I don't think it's a coincidence that most other UI toolkits have added something like flexbox (including iOS) -- it's not perfect but it fits how people generally think about UIs. Was HTML/CSS the first major UI framework to use flexboxes? That's how I remember it, but maybe it was copied from somewhere else.
It can be problematic regardless of the technical solution, though generally I have to agree with the loudest voices on this thread: SwiftUI is a load of rubbish, UIKit and autolayout (and Interface Builder) was better.
Regarding problems with all layouts: I've got a 2022 model iPhone SE, so smallest screen, and every so often run into an app which just doesn't handle the screensize right. I've seen this happen as a developer with both UIKit and SwiftUI, it's just the type of bug you end up seeing is different.
Multiple 'artboards' for screen sizes/ratios are the solution, which basically just means swapping out a .nib in Interface Builder. Better to just make it explicit.
It’s easy to say they were just trying to be trendy and thus the real flaw was the trend is bad and the fault of worse devs than us (the young web devs mentioned)
The thing that obviates that is the trendy stuff works, yet, SwiftUI doesn’t.
(source: I wrote ObjC/Cocoa as early as 2006, and switched to Flutter as my primary dev kit some years ago: it simply doesn’t have the performance issues mentioned.)
Generally, it is not young web devs fault that SwiftUI exists, and certainly not their fault it still has serious issues 7 years in. The things named in the article as not-working in SwiftUI do work in fine in the others.
Swift should have just been a much improved syntax over that same runtime. It would have avoided so many headaches. For one they wouldn't have made the awful decision to have return-type overloading and completely ruin the typechecker's performance in the process.
SwiftUI should have unapologetically been a convenient, reactive wrapper over UIKit and AppKit, rather than treating them as deprecated implementation details that devs nonetheless keep having to drop down into.
These decisions come down to ego, of wanting to do away with the old and carve out your own legacy separate from it. Nice if you want a promotion but not so nice if you're trying to make a long lasting ecosystem for developers to build upon.
At least Swift and SwiftUI have a reasonable interoperability story with the past. Can't say the same about Microsoft's graveyard of UI frameworks.
That's exactly how Objective-Smalltalk started, and it's still very good at being just that.
https://blog.metaobject.com/2019/12/the-4-stages-of-objectiv...
However, it has grown to be, er, a bit more.
https://2024.splashcon.org/details/splash-2024-Onward-papers...
https://objective.st
> SwiftUI should have unapologetically been a convenient, reactive wrapper over UIKit and AppKit,
I am also working on a UI "framework" I call InterScript that is (for starters) a wrapper over UIKit and AppKit, and basically solves what I perceive to be the biggest problems of Cocoa:
1. UI specification using object literals. This makes UI-creation very compact and readable. The following example (mostly) reproduces a SwiftUI "Form" example from Apple documentation:
There are actually even better ways of accomplishing this, but this should give you an idea.2. Better communication between model and UI by using the support in the language for polymorphic identifiers and dataflow. Because dataflow is in the language, it can be expressed succinctly without making it hidden magic like in SwiftUI. With dataflow and polymorphic identifiers, you also get a dataflow-constraint mechanism similar to Cocoa Bindings, but again with proper support and less magic.
Essentially the solution to this:
https://blog.metaobject.com/2014/03/the-siren-call-of-kvo-an...
There is more, for example cross-platform, MDA/Naked Objects/Direct2Web style simplification and web integration with HTMX and HTMXNative.
You can't have Cocoa without Obj-C, or at least a langauge and runtime with that philosophy.
Apple software has been on a clear decline for a seriously long time, and it's propped up almost entirely by them pulling off Apple Silicon combined with how Microsoft have somehow been even worse.
All of these are unfashionable nowadays, but they’re fundamental to Obj-C (some to the structure of the language itself, some just as idioms) and to the design of AppKit and UIKit.
Now, the fashion is:
Strong typing. Static binding at compile time with no runtime modifications to the type hierarchy. If OO is used, there should be minimal inheritance. Nullability is strictly defined in the type system, and acting on null objects causes, at its most forgiving, an exception, and at its least forgiving, program termination. Notification-based systems may be the outlier here (still in heavy use), but even they are often frowned upon for being too 'loose' and unanalyzable, at odds with the ideals of static typing and static binding.
One very important one is that, empirically, it showed how much of what we think we know about language design is ... shall we say ... "incomplete".
After all, Objective-C is a car-crash of a language: take some Smalltalk and jam it into C. Done. How can you write software with this? And yet NeXTStep and Cocoa/CocoaTouch, arguably the most elegant pieces of OS-level/UI-framework software ever, were written in Objective-C. And not despite of it, but because of it.
From a safety standpoint, it's hard to see how you can get worse: all the static type safety of Smalltalk (none) combined with the memory safety of C (none). And these interact.
And while it certainly is possible to use it very, very badly, in practice I haven't seen the horrors that we are supposed to get.
https://blog.metaobject.com/2014/05/the-spidy-subset-or-avoi...
As an example, we got the same level of improvement from doing an Objective-C → Objective-C rewrite with Wunderlist (from WL2 to WL3) that others claim for Objective-C to Swift transitions.
Also, dynamic messaging is said to be slow, yet Objective-C programs consistently outperform the much more static Swift ones.
https://www.amazon.com/gp/product/0321842847/ref=as_li_tl?ie...
And of course, we all know that to do dynamic OO, you need a large runtime and better yet a VM. But it turns out that you can get much if not all of it with a tiny sliver of an extension to portable PDP-11 assembly language.
https://blog.metaobject.com/2024/08/objective-c-is-just-like...
With so much being provided by so little, you can actually put the rest of the language design space to better use, IMHO:
https://objective.st
Message passing, these loosely coupled 'delegates', a mixture of hardcore C, needing to do memory management but also just passing objects around in the runtime... messy, weird... but in the end the right solution to make flexible but performant software. I learned a lot from it. I should dive into the history of NeXT one day.
Apple got rid of all the NeXT people long ago, with Tim Cook stabbing Scott Forstall in the back, so the answer is No.
If you were to build a system with no requirement for backward compatibility with cocoa or macOS, or even knowledge from such a thing existing, we have still moved forward three decades from not just NeXT, but the computing industry that NeXT was built to serve.
I'd assume their requirements would be drastically different, and the system they created would be drastically different as a result. The requirements aren't even easy to hypothesize, since iOS would never have existed.
In the “enterprise scene”, this sort of purge strategy is likely linked to a big percentage of money wasted and sometimes total failure.
Why do managers keep making this mistake? “Legacy” is only a bad word in IT. :-(
It is not like their knowledge and experience gets literally purged.
React works well, because it's only an abstraction over the real DOM. React only handles your app state. But the DOM mechanism is still very performant and very much imperative. But I don't think something like React would work well in a mobile app, because the UI tree is often very simple on iOS and macOS.
UI is also very much not functional, and in fact the lack of progress in UI the last 30-40 years can largely be traced to trying to create UI with procedural/functional programming languages, an instance of linguistic-architectural mismatch.
Further reading:
Programs = Data + Algorithms + Architecture: Consequences for Interactive Software Engineering -- Stéphane Chatty.
https://link.springer.com/chapter/10.1007/978-3-540-92698-6_...
Can Programmers Escape the Gentle Tyranny of call/return?
https://2020.programming-conference.org/details/salon-2020-p...
UIs Are Not Pure Functions of the Model - React.js and Cocoa Side by Side
https://blog.metaobject.com/2018/12/uis-are-not-pure-functio...
Beyond Procedure Calls as Component Glue: Connectors Deserve Metaclass Status
https://2024.splashcon.org/details/splash-2024-Onward-papers...
What is your thesis then? What is UI?
https://web.archive.org/web/20090424042645/http://heim.ifi.u...
View and model are related, but neither is procedurally dominated by the other. The view is not a subroutine of the model, or vice versa.
They are related entities that communicate in order for the view to function as a representation of its model to the user, and for the model to be manipulated by the user.
To get the details I really recommend the Chatty paper. It is a bit hard to read, but delivers the goods.
My working thesis is that UIs are basically video games. Just a gut feeling I can't really 100% put in words.
But essentially they're the same thing: Read input, update model, render view.
The difference is that for most games, throwing away the complete rendered graphics and re-rendering from the world model is often the right approach.
For most UIs, it isn't, unless they really are very close to video games, for example mostly passive feed readers, video players etc.
Why? Genuinely asking, this topic is very interesting to me.
The quote is from the original definition by Trygve Reenskaug, the inventor of MVC (see link above).
https://en.wikipedia.org/wiki/Trygve_Reenskaug
Here some more on that misconception:
https://blog.metaobject.com/2015/04/model-widget-controller-...
I disagree, and I believe that the complete stagnation of GUIs is due to ignoring this.
There is no good reason why a GUI system isn't:
Description->Pack->Apply events->Generate assets->Render assets.
At each point you reify the result into an artifact that is everything the next stage needs. This has a couple of nice properties. One property is that everything is deterministic and testable. Another property is that after the pack and apply, everything is now embarrassingly parallel. Another good property is that you have an artifact that the accessibility people can latch onto before you bury it under pixels.
That would be a very functional way to deal with GUIs.
However, we continue inheriting properties and single main threading everything like we're still on 33MHz machines with 8MB of RAM.
> I disagree, and I believe that the complete stagnation of GUIs is due to ignoring this.
I disagree with your assessment.
>Description->Pack->Apply events->Generate assets->Render assets.
1. What does that even mean? I don't see a UI in there at all, at best some graphics (Render).
2. That's not "functional". If anything, it looks like a pipeline, so dataflow. But then again, see (1)
3. Not sure why reification, that is turning things into objects, is functional to you. Reification, that is turning things into objects, is object-oriented.
4. MVC was actually created on 5.8 MHz machines with 128KB of RAM (including the display buffer). And still works beautifully today.
https://en.wikipedia.org/wiki/Xerox_Alto
And, um, side note: dataflow programming is almost always considered functional programming.
Object oriented, by contrast, is all about hidden state and mutation. I send a message or call a function on that object over there and fingers wiggle and magic happens. But I don't know what or when or even if it actually happened.
And increasing evidence suggests that MVC doesn't work beautifully today because it doesn't parallelize, and it scatters state between uncooperative things. Just ask every single GUI that exists--every single one hangs because somebody made an oops and put too much work on the single, blessed primary thread. Or they have janky scroll. Or resizes leave gunk on the screen. Or your system flashes and jiggles because it's too busy reflowing everything in the universe. Or ...
> dataflow programming is almost always considered functional programming
That turns out not to be the case. Dataflow programming shares some aspects with functional programming, they are not the same at all.
> Object oriented, by contrast, is all about hidden state and mutation.
That also turns out not to be the case at all. Heck, there were even object-functional programming languages.
> And increasing evidence suggests that MVC doesn't work beautifully today because it doesn't parallelize,
What does MVC have to do with parallelization, in your humble opinion?
What you described works only in super simple scenarios. Whink Web 1.0, when Javascript was used for basic form validation at best, and didn't change DOM that much.
Unfortunately when complex state transitions, async, and virtualization enters the discussion, the magic of React breaks, and you have to deal with all that, and also deal with how React's engine handles things under the hood.
Async is just difficult in general though. It's not really a surprise that most libraries/frameworks converged on similar designs.
React also operates on a virtual dom, there's no reason imo why couldn't they just fake that for you.
But, once you start hitting things like differently sized elements, search and so on, you start running into platform limitations that you won't be able to resolve in React land.
Which usually means this model loses all advantages compared to simple MVC, or imperative systems, and at worst, becomes another headache as implementation details start leaking.
But the rest of your app still gets the simplicity of a declarative programming model.
https://github.com/janestreet/bonsai
It's always going to be slower than using something imperative. Trying to process the entire world's state for the sake of purity can feel elegant but it isn't free. And the complexity that gets added to make things performant is worse than just accepting that UIs are going to require you to jump around the tree and modify state.
Every time I go through the trouble of understanding the latest web technique (React, Elm, Signals (the newest solution), etc.) to deal with state management and the DOM, I end up walking away disappointed. There's nothing new in them that you can use to improve what we've been doing for ages in native GUI toolkits.
And to jump back to the original topic, yes, Cocoa was pretty decent, and SwiftUI while nice in many ways tries to Reactify native macOS development and made it worse. And it made Swift incredibly more complex and worse in hindsight.
1. The UI tells the model to change.
2. The model does the change and possible related changes.
3. The model notifies the UI that something has changed.
4. The UI updates itself from the model.
Alas almost nobody does MVC, despite calling what they do MVC.
How do you collect all notifications on step 2 to fire them on step 3 such that UI does not re-render itself too much? E.g. updating a title of each item in a list of 100 items should not trigger 100 renders. Or 100 layout calculations (which I think is harder to avoid).
How do you deal with situations where on step 4 UI triggers an event that your model happens to listen and the cycle repeats while killing performance?
Because you rely on events how do you avoid “event hell”? That is, a situation when an event handler triggers a change that triggers another event handler that triggers a change and so on. Sometimes it is scrolling or typing, sometimes it is parts of the model subscribed to each other bubbling events to UI.
> UI does not re-render itself too much?
Glad you asked! In my Blackbird reference architecture (which is an instance of MVC), I use a coalescing queue to capture the updates. The coalescing is two-level: first, simple duplicates are weeded out. Second, if the update queue gets very full, it becomes coarser-grained, and weeds out duplicates based on that coarser grain. This has multiple steps of grain up to "just re-render the whole UI". Worked like magic in Wunderlist. Except it wasn't magic at all and very simple, inspectable and tractable.
> step 4 UI triggers an event that your model happens to listen
That's not allowed in MVC.
> Because you rely on events how do you avoid “event hell”?
I don't "rely" on events and there is no "event hell". Events are only used in the M→V communication part and there are no subsequent triggers, because the only event is "the model has changed", with an optional payload specifying which part of the model. Important: it must not contain the data that changed, this the view has to fetch from the model once it processes the update event.
Since the only event used is "the model changed", the view cannot ever be a source of those events, so no "event hell".
I don't. And I don't have to, as I delegate that sort of stuff (mostly) to Cocoa/CocoaTouch etc.
https://blog.metaobject.com/2018/12/uis-are-not-pure-functio...
When you have stateful view objects, these stateful view objects maintain the view state. When updating themselves with new data due to a ModelDidChange notification, they take care of reconciling their current display state with the underlying model state.
> When displaying a scrollable and selectable list of items
So for example an NSTableView or NSCollectionView. I personally use a subclass that interacts directly with a table representation, meaning a lot of the glue code that Cocoa(Touch) requires disappears.
> Who updates the UI state accordingly to make it valid again?
Always the view. Who else?
> In the general case, application code needs to be involved in choosing the desired valid UI state when the underlying model state changes.
How so? The view is always a reflection of the model data. Whether that is a "change" is actually mostly irrelevant, even though the notification is called ModelDidChange in my case. In Smalltalk MVC it is the #changed message. It means "you are out of date, please make yourself reflect the model".
This same mechanism also handles the model being changed by some other party without any further code. "The model has changed, please update yourself to reflect the current state of the model". That's it, modulo optimizations.
> How is the corresponding application code prevented from triggering further events?
Model code isn't involved. A ModelDidChange event is only triggered when...er...the model changes.
That said nothing prevents you from manually invoking the ModelDidChange notification, just like nothing prevents you from calling abort(), running an infinite loop, creating an unbounded recursion or reading from /dev/random until it is exhausted ...
Doing it by accident, though, is very hard, because it just isn't part of the programming model.
This is not about duplicates. For example, sync updates 100 items in a list changing their titles. Items are bound to a list in the UI. Thus, 100 unique title update events triggered.
>Events are only used in the M→V communication
I don’t understand. Button clicked -> model change -> view update -> new event triggered -> model or view updated again … This is not something one would code on purpose, but often an attempt to create relationships between view. Like a custom layout code. Might not include model at all, just views being updated in an event handler trigger more events and more updates to views.
Those "updates" go in the queue. When the UI gets around to updating itself, it looks at the queue and invalidates all the UI elements that refer to the model items in the queue.
It then updates those elements, using the coarsening to update larger elements in bulk if that becomes better.
> Button clicked -> model change -> view update -> new event triggered -> model or view updated again
Once again, that is not allowed. View updates are not allowed to trigger any events in MVC. A model → view update updates the view. That's it.
The only event is "model changed", so it also doesn't make sense for the view to generate those events.
Now to your questions:
> How do you collect all notifications on step 2 to fire them on step 3 such that UI does not re-render itself too much?
Diffing, and then caching very aggressively. The click causes the model to re-call the layout() fn to return the entire DOM, however, there are ways to make this step very fast (arena allocation / no allocation). Then this gets diffed with the previous DOM state and the framework internally reuses everything it can (with user providing keys for list items, like React does).
> How do you deal with situations where on step 4 UI triggers an event that your model happens to listen and the cycle repeats while killing performance?
Azul has a "max recursion depth" of 5 and then just throws an error (infinite cycle). So, it will invoke all the relevant callbacks for a frame, then "sum up" all of the Update enums (i.e. one callback returned RefreshDom -> now we need to repaint).
> Sometimes it is scrolling or typing, sometimes it is parts of the model subscribed to each other bubbling events to UI.
Scrolling, selection, typing, etc. are handled by the framework. To make something editable, you need to set "contenteditable=true" on the Dom node (like on the web). Then, on text editing (which can also come from IME, a11y input, copy-paste), you get a "text changeset". The callback can then "reject" the changeset or allow it (default, since you already set contenteditable before).
Azul has a "dual update pattern" for performance here, i.e. the DOM itself is immutable until the next layout() call, however for "quick edits" like dragging a node you obviously don't want to call layout() again and construct an entire new DOM tree. So there, you just (conceptually, don't know the current API for this):
So, if another callback fires in between, the data model is still properly up to date. Azul also aggressively reconciles focus, scroll position, selection, text cursor position, etc. But Azul does not allow "one event auto-triggers another" like SolidJS does, it looks nice on a slide deck and then is a pain to debug Rube-Goldberg state machines.This also works for text input or updating images (i.e. you don't need to call layout again on text input). Update.RefreshDom is for "larger / structural" changes, i.e. something like a route switch in a SPA-style app. Azul tracks the text cursor position by diffing the actual text, so the user code doesn't have to track the text cursor and state is preserved during a diff (it can also retain heavy elements).
For large lists, there is a native "virtualized view" DOM node with a callback that is being called "during" layout (after the size of the container has been determined, then the framework asks you to render your DOM, given the scroll position). So, that can be diffed, too. You never render in the DOM more than ends up on screen, so the perf is manageable.
Scrolling and retaining scroll positions inside a virtualized view is still an ongoing topic (not impossible, you just have to have functions to measure the DOM items before you return them, to estimate how much you need to render, and then do the math for "where are we right now, where is the scrollbar, how big is the virtualized view in relation to what we're rendering" - so the framework can set the right scrollbar size and position).
Again: please don't use or post Azul here on HN yet, docs are still slop and undergoing review, API is unstable until I have some apps going, but I just wanted to answer these questions.
[1] https://azul.rs/ui/
Is the UI updating itself automatic or manual? Because if it’s manual, that’s precisely the error-prone part that you’re saying this approach somehow solves - you’ve done the “How to Draw an Owl” meme. If it’s automatic, that doesn’t seem especially different from the React/Redux/Elm/SwiftUI approach (as a sibling points out).
Different formulations of M-V-C have the C deal with more complex interactions, with sequences of interactive prompts like wizards.
The update is essentially automatic, and yes: MVC already solved the "problem with MVC" React/Redux/Elm/SwiftUI claim to solve. In 1979.
Business logic is supposed to go in the model. All of it. Because it's the important part.
Controller these days can be largely empty.
"MODELS Models represent knowledge. A model could be a single object (rather uninteresting), or it could be some structure of objects.
There should be a one-to-one correspondence between the model and its parts on the one hand, and the represented world as perceived by the owner of the model on the other hand. The nodes of a model should therefore represent an identifiable part of the problem.
The nodes of a model should all be on the same problem level, it is confusing and considered bad form to mix problem-oriented nodes (e.g. calendar appointments) with implementation details (e.g. paragraphs)."
https://web.archive.org/web/20090424042645/http://heim.ifi.u...
"We solved the problems of MVC by properly applying MVC".
https://blog.metaobject.com/2017/03/concept-shadowing-and-ca...
Conceptually, the UI re-renders itself completely in order to always be an accurate reflection of the model.
That is the #1 job of the view: be an accurate reflection of the model.
And re-rendering itself completely is a safe way to implement that requirement.
However, the UI can also look at the model in more detail and figure out what parts need to change, as long as the effect is the same as re-rendering everything.
And the model can tell the view that specific subparts of the model have changed to make that job easier for the view.
But if it can't figure out the details, the fallback is to re-render the entire view from the model. But not to recreate the view. The view sticks around.
One way of doing this optimization is "damage rects" like Cocoa does. Another are the polymorphic identifiers used in the update queue of Blackbird.
MVC, the controller is the intermediary between the services/data models, and the views. That still one of the best / simplest way to build large apps. MMVC is just a variation of it, with the models being able to communicate state to views and bypass controller if needed.
MVC, is still one of those 'fundemental as simple as it gets, and it gets the job done' patterns.
Your interpretation is a common misconception, for example promulgated by Apple. It is not MVC.
https://blog.metaobject.com/2015/04/model-widget-controller-...
https://blog.metaobject.com/2017/03/concept-shadowing-and-ca...
"A view is attached to its model (or model part) and gets the data necessary for the presentation from the model by asking questions. "
https://web.archive.org/web/20090424042645/http://heim.ifi.u...
I didn't say that.
User interfaces representation are mostly trees. And with functional programming you basically have Tree2 = f(Tree1). Until f is done you can't do anything really. React has a lot of escape hatches to improve performance, but they are escape hatches, not an endorsement of the architecture.
With imperative programming (and OOP), you only have that single `Tree`, which you update at will. Less elegant yes, but we have modularization to help us there. What Emacs does is to keep that `Tree` as a single mutable object, but have the code be functional, while the results are imperative.
I don't think we have to wait 10 years, we can say it today.
In fact I can think of at least three instances (at very different magnitudes) where Apple has dragged itself out of a stupid hole they dug for themselves.
Because it was good.
I’m no huge apple fan, but I didn’t really think the 17 was more than a regular boring spec upgrade, which seems fine all things considered. (Currently on an iPhone fucking 17)
Data Flow: The author claims there’s no way to know when things update. Not only does experience help here but there are profile tools that tell you when and where things are updated. This isn’t black magic. Keep Views small, be careful how you hand around data. @environment is super cool but can have a cascade effect. This was greatly improved iOS 17+ and I wouldn’t support anything older than iOS 17.
GeometryReader: Occasionally I’ll use this. It’s kind of a necessary evil when dealing with certain view complexity. It can also be a sign that you’re doing something wrong.
API Stability and performance: Apple users upgrade. There’s no reason that you should be supporting iOS 17 at this point — even iOS 18 is roughly 2%% of our user base across several apps. I’ve been using SwiftUI without major performance issues but I also don’t early optimize. I profile and fix as needed. One of the early studios I worked for wrote all our games in UIKit as prototypes, when performance tanked we’d switch to the appropriate tools (eg. OpenGL) where it was necessary — like in the core game.
I could go on but in the end just use the right tool for the job, if you’re not proficient in SwiftUI or it isn’t going to work for your cross platform project, you have a lot of other alternatives. For me though, it’s been amazing to work with. I stepped away from iOS programming for 3 - 4 years because I was burnt out using storyboards, dealing with massive view controllers, and all the boiler plate it’d take to get a view up and going in UIKit. SwiftUI roped me back in.
* Quick addition edit: Cross platform for iOS, iPad, macOS has never been good. I’ve found recent updates have made things better to the point of tolerable and it’s nothing like when we had to post-fix an ~ipad to our Nibs — There has never been a ‘glory days’ of cross platform Apple UI libraries.
SwiftUI is great for "surface level" UI, that has some basic data bindings - think a basic CRUD app, which needs some navigation, and the ability to scale across the smallest iPhone to the largest macOS screen, from touch gestures to mouse input.
If you ask anything more of it, then you need to start branching off into specific libraries / tools / frameworks (UIKit, CoreAnimation etc) - which is much easier now too, but you'll always have a bad time if you try to mix the two in a single "view" / "frame".
I'm not surprised that's still true today.
Strong disagree on that. @environment is an amateurish hack, basically sugar-coating global variables as a solution to SwiftUI's poor design.
I had a strong background in UIKit; then for a product I'm building for myself, I decided to go all-in on SwiftUI. This was after it had been around for four years or more.
SwiftUI turned development, which I used to enjoy and feel good about, into a tedious trudge. I read everything I could, did the Stanford class, adopted "best practices," and really made an effort to do it right. It blows.
Unless your app is a trivial master/detail data-viewing app (as pretty much every SwiftUI example is), you wind up thrashing and performing all kinds of state-tweaking gymnastics to herd your application along through whatever tasks the user is supposed to be doing. Heaven forbid you need to walk the user through a series of steps to do or create something.
It's going to be a testing nightmare, and it suffers from every bit as much opportunity for data to get out of sync between the model and the UI as "traditional" app structure. Apple touts the "single source of truth" as gospel in SwiftUI, but you can't have that. First of all, Swift's official position is that you should "prefer structs" over classes. But (and this is one of Swift's hokier characteristics) structs are passed by value (copied) instead of by reference. So your "single source of truth" is broken after the first function call; your data are copied all over the place.
But there's another problem with the single-source mantra: You can't just expose your core model to the UI for direct manipulation, so you have an intermediary (the so-called "viewmodel"). But that intermediary must have temporary data structures to shadow those in the core model, so the UI isn't messing directly with the model, and the user can cancel or fail when changing things without messing up the integrity of the model.
So now, once again, you don't have a "single source of truth."
The problem isn't understanding the paradigm; it's making it do useful work. Some people love to mock OO for its early and obviously cumbersome and pointless idioms, which were quickly abandoned by experienced programmers. What remains of OO is still quite useful. I predict the same for... whatever the this mess is called. You waste so much time trying to follow the gospel of "MVVM" for no actual benefit. As I went through it, re-reading and re-digesting various pundits' viewpoints... I realized that I just had to start from scratch and build something that pays off instead of a bunch of useless ceremony.
I switched everything to classes, built managers (controllers) for the big categories of data and tasks I need to organize, and inject whatever objects I need into each view.
As for the rest of SwiftUI, its state is disgraceful. It excels at scaling UI for different screen resolutions; something that Apple neglected for waayyyyy toooo long. But there was no excuse for Apple to release a UI framework that basically didn't support the most fundamental UI paradigm of phone applications: a stack of progressive views that are programmatically manageable.
How many half-assed attempts has Apple trotted out, to do what UIKit does with ease? The latest is NavigationStack, which is still pathetic. The only way to navigate more than a level deep is to create an array of one datatype to serve as NavigationStack's "path." But this is designed to be an array of a single datatype. Look at the examples for this thing: They're applications that present a stack of views that each show... an INTEGER. In decades, I have never written an application that needed to stack up a pile of views that all show the same datatype.
And yes, I know the workaround for this where you create your own struct datatype and then fill it with enums, one for each view. But come on; the fact that Apple even rolled out this ludicrous design tells you that the talented architects have left the building.
It's used a few different ways in the app I'm looking at now. One is to hold a source of truth for my API data models. This way I have a cache of say User that, when it changes for whatever reason - maybe invalidating the cache (read logout) or changing a profile image - is handed around to all my Views that need User info with @Environment(\.user)
Same thing with my analytics. Something like a MixPanel is only going to be created once. It's a singleton. You pass it around in an @Environment.
NavigationStack was a problem pre-iOS 17 and even a bit of a jam in 17 -> 18 and was glad to drop that version. But passing around an enum of values makes deep linking intuitive, yes there's a bunch of boiler plate - setting up an enum I guess - but deep linking was never easy. If you're not doing deep linking then a NavigationPath is really simple to use but I assume that's not what you were talking about.
I used MVVM for about 6 months and ripped it out. There's no reason to use that pattern in SwiftUI. It was popularized by certain iOS evangelists and caught on with the newbies (myself included). Your reaction to MVVM and useless ceremony is exactly the response you should have to a code smell that doesn't belong and it was mine too.
You can use a tagged union for the "one datatype", thereby allowing your views to accept any datatype you provide in the enum. Or use NavigationPath.
And it's pretty much incapable of making anything that is not a master/detail with endless lists within lists within lists.
Just look at the shit that Apple regularly ships now: it's just endless lists of lists.
After two many trial and fail, now it's quite clear to me that for simple UI I will use swiftUI(such as help sheet or simple toggles), for complex and performance first, I will just use UIKit instead, it save a log of time and actually the imperative UIKit is also quite easy to read and review
the feasibility of review is important because code is not mainly written by agent, though as my understanding of UIKit grows I can smell the bad part and let it rewrite
I worked at a FAANG and a team was tasked with implementing a new REST framework to replace/augment the supported RPC framework. Metrics were very important and this team might have know HTTP/REST well, but they didn’t understand what operators needed. It wasn’t even on their radar. As a senior engineer, without much traction I complained and fortunately someone one level higher from across the company saw my message and had the necessary influence to get them to pause and think. I don’t know if anyone has done that at Apple.
Things that used to work universally - key bindings, drag and drop, context menus - just don’t work by default anymore. Why? Because now everything is some low level UI element and whose behavior is completely up to the programmer. Sounds like web programming, not like Mac programming.
From a programming perspective, I don’t even like the paradigm. Once understood, IOC in AppKit and Interface Builder was incredibly efficient.
Autodesk (since you mentioned CAD) itself dates back to 1980s. And even then, they had at least 15 people working on AutoCAD. That's a small team size. Today, they have over 14000 employees. Some random website tells me they had ~5000 of them 20 years ago. You can make anything work when you throw an army of people at it. It's not exactly a good point towards small teams being able to build complex imperative/OOP apps.
That's not to say that Apple is not dropping the ball here. I don't really have any Apple devices to check for myself, but I know that Microsoft, for instance, has been doing much more than just dropping the ball when it comes to UI. But, I'm not sure that has anything to do with imperative vs declarative.
These frameworks have a number of good ideas but they don't necessarily combine in a way that transcends high quality traditional imperative frameworks with declarative-reactive bits sprinkled throughout, at least for more complex apps. SwiftUI and its ilk work best for super simple tabs-and-flat-lists sorts of apps.
And because of the open source nature you can always drop down in layers, just a few weeks ago I made a very specific engine optimization, all while the application code on-top can stay declarative!
It also doesn't fix problems inherent to declarative UI, like readability breaking down easily and certain things that would be a cinch in an imperative framework being extremely awkward to implement.
The main difference between various retained, OOP, functional, immediate, declarative, ..., approaches is how they treat this state.
For imperative/retained/OOP libraries, you operate on this state itself. Your nodes/widgets know their own state, how to render themselves, their place in the hierarchy and so on.
For immediate/functional(?) libraries, this state is a cache. It's not something you work with directly.
Despite not really liking React itself, I think it has found the best model.
You take a retained core, possibly OOP, maybe ECS or whatever, and you write a declarative wrapper around it. This lets you escape the easy-mode declarative landscape when needed, but most UI can still be simple to write.
In my experience the solution is often to use the appropriate architecture underneath your UI layer. Basically you build a data structure that represents your UI and always hand this entire structure to the declarative UI layer. Underneath the UI layer, you can still use imperative code to manipulate the data structures. The benefit of the reactive/declarative approach is that you don't have to think about how changes in the data need to be reflected in the UI. That's the framework's job.
Note: With "data structure" I don't mean "build a shadow DOM". I mean something specialized to your use case.
In SwiftUI, that means endless chains of modifiers, and in Compose this means monstrous constructors and modifier chains. Both get really ugly and painful to read quickly, and there's not a lot that can be done about it apart from breaking everything out into smaller views (which only goes so far). The amount of boilerplate saved isn't worth the trade, in my opinion.
In an imperative setup, there's still a lot of code but there are more options for organization, readability, and overall clarity. One can break things up with comments, break out setup into functions with self-explanatory names (that the IDE can then quick jump to, as a bonus), etc.
Yes, it's easier to get tripped up with imperative frameworks if one isn't thoughtful with managing their data, but much of the time that code only needs to be gotten right once.
Which is now being fixed by the Styles API (https://developer.android.com/develop/ui/compose/styles) which are easily reusable.
> Data flow in SwiftUI is indeed reactive—but sometimes I wish it wasn’t, because it’s reactive in all the wrong ways. It often reacts to changes it should ignore, and it ignores the changes you actually care about. To me, SwiftUI’s reactivity is a black box: It makes achieving predictable behavior almost impossible.
In Compose, seeing rememberXXX(key1, key2) sprinkled all over with keys makes following the code difficult.
Then add some side effects like LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { ... read permissions and render warning if we can't do something ... } and it becomes even more difficult to comprehend. Much of the Android framework APIs are not reactive, and polling on these UI events is still necessary (permission could have changed if the user put the app in the background, and you can't listen to them via Flow etc).
As the author says, these frameworks make the static data dependencies explicit but often at the expense of what is changing and why.
When I see rememberXXX(key1, key2) { } the first thing that comes to mind is, why would key1 and key2 change, and often that is not obvious.
Just MHO, and it’s not going to stop the juggernaut, but there’s just no appeal in moving there for me :( If (when ?) Apple drop ObjC, that’s the day I move to Linux
SwiftUI is not Swift. It is implemented using complex Swift features, but it is a huge step backwards in dev-ex from autolayout and UIKit.
Unfortunately although Swift seemed promising at first, by the time Swift 3 rolled around a lot of people were actively frustrated and moved on from iOS development. Having actual experienced hands guiding that ship could have led to something great instead of the mess that is there today.
Memory management, Generics, Fast enumeration, Properties were seamlessly added to ObjC over the years without adding to the cognitive load of the language, which is minimally more than that of C. It’s a small superset of C and (for me) hits that complexity/expressiveness sweet spot. YMMV, of course.
I hated the properties addition in Objective-C. Why add that and not a dot syntax for all messages? Having a dot operator in a pointer blurred too much of the line between C and Obj-C syntax for my taste.
Agree that SwiftUI was just jumping on a bandwagon and would say that the design of SwiftUI clearly strains the poor language design choices in Swift.
Swift is incredibly better than ObjC on so many ways it’s just not comparable. I used it since day one and never looked back. (And I was deep into the ObjC ecosystem, having written very low-level frameworks, and having loved it.) Yeah, first versions of Swift were raw, but now it’s just THE language; I used for everything (obviously Apple soft frontend, but also the web, the backend, etc. Even android dev I would do with Swift though I do not have the occasion for now.)
Apple will never drop ObjC support IMHO. But most new frameworks will be Swift-only.
SwiftUI is a step backwards from AppKit in the sense that we lose control over what’s possible when using it exclusively. But 1/ it’s much simpler for doing simple things and 2/ we can drop down to AppKit when needed. All in all, it’s good that we have it.
New things (especially 12 years on) shouldn't be "do simple things simpler, and drop down to old ways for complex stuff". It should be "do complex things simpler".
You strongly disagree with what? That new tools shouldn't just make simple things simpler?
> Make me write less code, make me spend less time fixing it.
But that's exactly where SwiftUI fails, doesn't it? The moment you step outside the "the only UI you can do is lists", you are exactly in the "write more code with weird failures" territory with "just fallback to AppKit for anything even slightly outside of the extremely limited sandbox".
If you don't think that way, or you're debugging somebody else's layout, then yeah, it's a nightmare. But it's shockingly easy to just redo the whole layout in that case.
For my app which is a AI chat app, I needed to load and show a large number of chat items in a list, SwiftUI is really bad at this. Another issue is, most of Swift markdown libraries don't perform perform well because each elements are rendered as SwiftUI views which introduced a lot of issues So I built my own renderer using TextKit. Even basic things like Settings window is broken. But I still prefer using SwiftUI as It gets the work done faster and I can always fallback to AppKit.
I find that web tech like React are worst than SwiftUI. React also has re-rendering and state management issues
The boundaries aren’t perfectly clean, and that’s fine. But the separation gives you a useful way to think: structure this first, style it later, add behaviour where needed.
My experience with Compose—though I suspect SwiftUI people will recognise the feeling—is that I have to think about everything, everywhere, all the time.
Then we add some MVVM/UDF flavour. The "ViewModel" knows nothing about the view, despite usually serving exactly one screen. Add some "MutableStateFlow"s, combine them into "ScreenUiState", expose it as a "StateFlow", collect it with lifecycle awareness.
Beautifully decoupled. Extremely testable.
Then the organisation writes no unit tests and relies entirely on two-hour nightly screen tests.
A welcome-page refactor breaks the profile page.
“Didn’t you check the nightly build?”
No. It runs at night.
“Well, that’s your responsibility.”
But you broke it.
“Yes, but it’s your code.”
Then why did we ship it?
Fine. Schedule the postmortem with my mother.
And I’m not blaming mobile developers here. I’m frontend, backend, full-stack, I think AI engineer now. I have personally helped make simple things complicated across the entire stack.
What I like about the web is that one simple screen can be vanilla JavaScript. Another can use Vue. Another can use some specialised spreadsheet component.
People react to that with horror: what if components are duplicated, behave or look slightly different?
Fair concern. But that is real coupling with visible consequences and trade-offs. Somehow we have started treating coupling as something abstract that only exists inside code, rather than something that should produce an actual benefit when removed.
HTML. CSS. JavaScript. Or something close to it.
Maybe I’m getting old.
I think this is familiarity speaking, which is what you're expressing earlier in the comment anyway. The reality is that we have to think of everything when telling a machine what to do. Exactly how we get that done is preference.
I guess I'm even older, because I prefer HTML4, without CSS. And I like using tables for layout instead of divs.
I always hated CSS.
I think this is true. SwiftUI became "very good" as of iOS 26 (in part because the performance gap mostly evaporated) and continues to get better in iOS 27. Over and over, I see UIKit developers trying to do things "the UIKit way" in SwiftUI, and they'd rather write TFAs instead of considering that they may need to skill up and learn to write effective and idiomatic SwiftUI.
Well I've been doing this for a pretty long time and I'd like to think I'm pretty good at it.
Personally, SwiftUI makes the 80% so much easier that, even if the remaining 20% requires dropping down to UIKit, it's worth it.
SwiftUI/React/etc don't introduce that pattern, they simply enforce it (and add efficiencies).
If a developer isn't familiar with the pattern, it's not because they are a UIKit dev, it's because they are inexperienced.
This is incredibly frustrating, particularly now that more UIKit and SwiftUI widgets share underlying implementations.
On macOS it is still comes up short on a lot of the GUI functionality. Stuff like window management, decoration, focus, undo/redo, finder tree type views etc. What Apple have implemented seems okay to me for iPad, iOS etc, but is not up to the standards users' expect for non-trivial native desktop applications.
With enough determination most of the omissions on macOS can be worked around by breaking the SwiftUI encapsulation and delving into AppKit or jarringly inelegant solutions. All of which are somewhat liable to ended up binned when/if Apple pull their fingers out. I had higher expectations of Apple, and overall, it's easy to understand why it does not have a stellar reputation.
As to why it's a bit rubbish on macOS; SwiftUI is largely a mapping to UIKit, AppKit etc primitives. At a guess Apple wants to reduce that number and are seeking to minimise investment in moribund technology.
All this goes away if you use a language with RAII, dont treat your devs as morons that cannot manage resources, and allow procedural GUI - let smart dev fix layout and pixels per inch. Artist can create mockup screens in photoshot or after effects, devs do actual procedural coding.
But no, we’ve gone the LEGO assembly way to avoid hiring smart devs.
Disclaimer - I do graphic engines with GUI toolkits for a living.
I get people are upset, but the edge cases and frustration in no way feel like fundamental failures—just stuff they haven't gotten around to yet. Yes, they should have gotten to them all sooner but that doesn't convince me they won't eventually.
There are still a lot of rough edges when it comes to look and feel on Apple platforms but it gives me the performance and speed while also being multiplatform.
SwiftUI is a laudable attempt to idiot-proof UI, but it sacrifices too much and ultimately fails.
/s
1. the language had all the right hook points to replace python - but then it was closed off in the apple ecosystem for a while. then it was made to be complex as C++ as time went on. if Swift had remained as simple as Go - and Apple had made a push for swift to go beyond apps in their ecosystem the language for data/ml would be swift
2. in regards to swiftUI - almost the same point as 1. react native took over cz it was a simpler more open ecosystem. then eventually most people stopped bothering with native apps (they're used to track you) - web apps are equally good. hence for most people they use native apps for maps, banking.
NavigationStack has been around since iOS 16, @Observable since iOS 17. and I'm not sure if the author is aware that GeometryReader hasn't been necessary since iOS 18 added onGeometryChange modifiers. Nearly 100% of users are on iOS 16+.
I'm doing some fairly complex work with SwiftUI and I find most components work identically between iPad and macOS. I can work for a week without needing to test on an iPad.
There are problems with SwiftUI for sure: I'm finding macOS performance on an M2 Max is far worse than an iPad M1, especially with animations. Toolbars are very inconsistent between platforms and the compiler timeouts are a real pain (hopefully Swift 6.4 will fix that).
I think the author does not understand how and why to use GeometryReader at all. He literally said "you find yourself wrapping everything in a GeometryReader" which is a different thing from simply measuring. For measuring you could always put GeometryReader into `.background()` and use that to avoid messing with the view layout. Also, "wrapping everything" is a good sign you are doing something wrong.
Edit: by the way compiler timeouts are not a SwiftUI issue: it is a Swift issue. You can create a timeout situation in pure Swift. For SwiftUI specifically this situation is addressed in the upcoming OS27 SDK.
Regarding GeometryReader: Just read your comment out loud.
What does this even mean? There are hundreds of thousands of apps in the App Store that are 100% SwiftUI. They are real. And they are very much "production grade".
The only people still complaining about SwiftUI 7 years later are the UIKit holdouts that never took the time to properly learn how to use it.
The first is a statement of quantity, the second is a statement of quality, dubiously supprted by the first.
The Mac Settings app still lags between panes years after it was redesigned to look like iOS. I would think that if they had a viable way build a high quality and performant app with even relatively basic UI components (if they cared to do so) they'd do it for the 1 app that's deployed to every mac.
SwiftUI does work in certain circumstances, and does work for allowing people to shit out their ideas faster, but it has struggled with the aspects described in the video. Some companies don't care either, and turnaround time is paramount, but in this discussion it's about quality compared to what came before.
SwiftUI is great for test harnesses and admin utilities, but I won't use it for shipping software. I have one app that I rewrote in SwiftUI, just so that I can say that I have shipped it, but I am still using UIKit for most of my apps.
I'm not thrilled with UIKit, but SwiftUI has kind of withered on the vine.
It is a newbie trap. It is great at producing simple apps, or things that don't require intense scrolling, or anything with heavy animations and precise layouts, but when you do something smooth, it is not it. It feels more of a React Native competitor, than a true UIKit replacement.
Also, almost everything that Apple has re-wrote with SwiftUI, came out worse as before (Settings, Spotlight, etc), and that doesn't help.
With AI coding... SwiftUI lost its edge/advantage (easy to layout screens), as now you code less of that directly, and might as well just go fo the framework that allows the most flexibility and gives you the best results for your users.
Apple really needs to either double down on it, and make it such that it has everything that UIKit has (match both features and performance), or just turn it into another optional framework, just as Interface Builder (.xib files) back in the day of Objective-C.
Right now it heavily promotes it as a first class citizen, meanwhile the features are not even parity with UIKit. It is so misleading to newcomers to the platform.
Ps. The other upsetting thing about SwiftUI, is that it has hurt the Swift language as well, as the team has had to introduce all kinds of hacks, or obscure features to the language in order to make it work, which made even the Swift language experience worse and more complicated than it should have been.
On the contrary, I think AI has made it EASIER to approach SwiftUI now, because AI makes up for SwiftUI's biggest weaknesses: the many ways of doing everything, Apple's wonky documentation and the need to know when to fall back to AppKit/UIKit.
In car terms:
UIKit - Manual Transmission - you control everything, but a bit of a chore
SwiftUI - Slushbox Auto Transmission - easier to drive, sucks for performance
UIKIT+AI Coding - Dual Clutch Transmission - both great performance, and easy to control/drive
But, SwiftUI is being pushed as the way to do UI, and as a replacement for UIKIt/the future of apple, where it is not even near feature parity with it. That's the most troubling part of it.
I wished apple just made it as a Template Rendering framework, and integrated wit with UIKit, and just modernized UIKit a bit.
Apple has at least been consistent on UI frameworks.
WPF is still around and have been spruced up as of late.
UWP was the DOA Windows 8/8.1/10 app format that was super restrictive, strange to develop for, and non-portable. It's basically MS's equivalent of SwiftUI.
Back when I wanted WPF to succeed, Microsoft was barely using it in any of their own apps.
Apple has used SwiftUI in their OS more than MS/Windows did, and there's quite a few apps on the App Store that -seem- to be made with SwiftUI.
I can render Metal shaders trivially in SwiftUI. Rendering glows, and blurs, and animated effects is much easier in SwiftUI than in UIKit, just use `.blur(radius:)` or `.blendMode(...)`
I have used AppKit and then UIKit since its inception. Creating visual effects like layer masks that modulate the opacity of underlying views is trivially easy in SwiftUI — far easier than the boilerplate and constant bookkeeping that CALayer's mask requires.
So a lot of the advanced full-screen animations in some of my games and apps are SwiftUI, because they are performant, provide the cool effects and animations, and work great. A lot of the simple get-the-job-done views and tool palettes in my apps are also SwiftUI, again because they don't ask much and get the job done, and look great.
However, where SwiftUI falls down is exactly what was demoed in the video: large collections of thumbnails that fetch asynchronously? Use UIKit. Multi-thousands of items in large, complicated lists? You can try SwiftUI, but you'll need to learn how to optimize it.
Other things, not mentioned in the video, that are more annoying in SwiftUI: want to take control of a transition between views, end-to-end? Not really possible in SwiftUI. There are bugs with ZoomNavigationTransition that affect all of Apple's own apps, and you aren't gonna be able to fix them without switching to UIKit.
> We started with @State, @Binding, and ObservedObjects. Then Apple realized the performance was disastrous and SwiftUI was re-rendering views all the time. That’s when it introduced the Observation framework and the @Observable macro. They tried to solve the problem with compiler tricks, but it clearly wasn’t enough so the layout engine continued its guessing games.
Not why @Observable was introduced
> In SwiftUI, you can never know for sure how many times a view will update and, when it does, why it chose to.
Instruments tells you these days
> That demo project from the SwiftUI tutorial has a very standard, non-custom one. You build the project with the latest Xcode and launch the app on the latest macOS—only to get this.
Yeah, it's a demo marked as "this is old, please do not use it"?
> What is a SwiftUI problem is the overall fragility of UI layouts. They fall apart in the most unexpected ways and at the most unfortunate moments. You can see it in the very real, production apps like UTM. It’s a fantastic piece of engineering, but its reliance on SwiftUI sometimes makes it feel like an early prototype.
This is an app written by someone who spends most of their time writing graphics APIs I think the fact that they can do something half-decent is really a testament to how approachable SwiftUI is
> In the end, you find yourself wrapping everything in a GeometryReader. And this is the ultimate admission of defeat.
No I only use GeometryReader when I actually want to do some coordinate math
> Okay, maybe you want to let your users customize the window toolbar, just as they could since 2001 (or something like that). Well, SwiftUI received this “breakthrough” feature only a few years ago.
iOS 14 my guy, this is literally one year after SwiftUI was released
> And then there’s the most basic task: displaying images you fetched from the network. Well, you better write your own fetcher, because AsyncImage was introduced only in iOS 15.
Can you point me at the API in UIKit that lets you do this?
> But if you want to also cache those images, I’ve got bad news for you: You can’t do it at all because right now, in July 2026, this API is still in beta.
Or this?
> For all these scenarios, developers usually come up with their own hacks and workarounds.
Yeah, it's called "you download one of a handful of libraries to do it for you". Now you don't have to do that.
I went through Visual Basic, .NET, WPF, Cocoa, and other random frameworks all professing to be the promised panacea for UI, but I think SwiftUI+SwiftData is the best environment ever.. IF only it could reach its full potential, i.e. do everything that Apple's "legacy" APIs can do.
I even tried using SwiftUI for games: https://i.imgur.com/5aTWbft.mp4
The biggest/worst hurdle in the "modern" dev experience is Apple's insistence on a yearly update cycle and the way they advertise those updates: You have to wait for the next WWDC and suffer through videos of uncanny-valley presenters, hoping to catch a glimpse of something that fixes the shit that was bothering you since the last WWDC.
3rd-party sites like hackingwithswift.com & swiftwithmajid.com provide invaluable info that Apple's own docs should.
At least the Swift language has been getting more regular updates since it went open source.
There's no way I'd dare to take on a full Apple-platform app project alone on my own, but I've started dabbling in it again thanks to AI: Codex even converted an old app I made in Visual Basic 900 years ago and had it running in SwiftUI within minutes!
I've even tried to get AI to sift through the WWDC video transcripts so I won't have to waste my mortal lifespan on that.
You may like my project https://charleswiltgen.github.io/Axiom/ (FOSS). I was in the same place a year ago, and initially created Axiom as a private skills suite before deciding that it was too helpful not to share.
And that's really sad, because earlier Mac OS X (and even OPENSTEP to a degree) was an Eldorado for boutique developers, not least due to frameworks like Cocoa and Objective-C (despite all the hate it seems to get).
If you knew C, it was not hard to grasp Objective-C (at least it was much easier than say C++ and MFC on the Windows side of things).
My first Apple purchase was an iPad I got for my aunt, and I loved how streamlined yet powerful it was so I installed a VM on Windows to dabble in iOS development, and fell in love with the sheer consistency of macOS, iOS and their APIs.
This was during the era when Microsoft was still figuring out whether to keep the Start Menu and replace the whole Windows UX with a tablet UI, so it was an easy jump.
Almost never looked back, and whenever I do I'm glad I jumped.
Then came Swift and I loved it, but then it took literal years to catch up with everything you could do in Objective-C with the Apple APIs. SwiftUI is having the same problem but for much longer :(
I don't get this part. You can literally rewrite Obj-C code verbatim in Swift and it will work. The only missing part is C macros.
It took a while to get there. They didn't have native Swift APIs for some things like URIs etc until later.
That is, pure native apps, can integrate KMP libraries. They cannot integrate Flutter libraries.
In other words, if I write a KMP library, I can ship it for multiple platforms and developers can use it in their Flutter project, or in their pure Android/Kotlin project, or in their pure iOS project.
If KDE can develop a high performance stable desktop, you can design whatever.
I don't know what your experience is, and I mean no offence or anything, but the only people I have seen who were happy with Qt for mobile development were people who had never tried to do it with a modern language, like Kotlin.
With Compose Multiplatform and Kotlin Multiplatform, you can write a cross-platform app in a modern language, and that is far better than C++.
SwiftUI is good, albeit not without issues, as long as you tolerate them. The same is true for any approach. My most recent app was built in SwiftUI because I have been using React Native in my professional work for so long I wanted a change of scenery.
Each approach has its issues, and it all boils down to a matter of preference and which tradeoffs are appropriate for the project.
All that to say, I don't think that vibe-porting will give you more than cross-platform. With cross-platform, at least your engineers understand the codebase.
1. It uses the builder pattern for views (familiar to those who used Java) but for some reason they decided to make it so that the order of the modifiers in the builder matters. Each modifier doesn't actually modify the main view but it modifies what the modifier before it decided to return. This makes no sense as the modifiers should each be modifying the main view to make everything predictable and easy to debug. I'm convinced no one (not even senior devs with 5 years of SwiftUI experience) understands how the ordering of modifiers works. It's just swap them until it does what you want it to.
2. The view lifecycles and code execution path seem random and hidden behind layers of "magic," making it incredibly difficult for developers to trace and debug issues.
3. It is practically impossible to set breakpoints for rendering and view construction, it's impossible to really figure out when re-renders happen and what drives them. I'm convinced SwiftUI apps are incredibly slow not because the SwiftUI implementation itself is slow, it's because, even Apple's own apps probably do a bunch of unnecessary re-renders and one no one seems to have any idea. This is unfortunately another design issue that can't be solved by just making SwiftUI more efficient. It requires simplification and tooling to help developers not footgun themselves.
4. Lots of issues start appearing later on in the development cycle because, for simple apps, bad SwiftUI design decisions and footguns have unnoticeable effects, until the apps gets more complex and things start breaking. Fixing these issues sometimes requires rewriting whole features or spending hours debugging.
5. There seems to be almost no documentation on Liquid Glass. It's laughable that after more than 1 year, Apple has simply refused to document or provide good examples for Liquid Glass, except for maybe couple pages that resemble the brain dump of an engineer that has never passed a writing class in college?
6. Stuff seems to be rapidly changing and breaking from version to version. It took days to make my app look and work the same in iOS 27 as it did on iOS 26, even though iOS 27 is supposed to be a minor bug fix release. We don't even use anything non-standard and don't do any hacks. This defeats the whole purpose of a simple UI framework that can be easily adopted to different platforms (this never used to happen with UIKit).
7. View debugger still has no SwiftUI equivalent. It used to make things so much simpler in UIKit when you could just see the view bounds, pick views apart and understand what's actually happening. SwiftUI has no equivalent other than `.background(.red)`. Terrible.
I don't know how Apple can salvage this beyond just undoing some of these terrible design decisions and making it 1. super simple to work with, 2. stop relying on magic, making things more explicit, and 3. providing actual 1:1 UIKit feature parity.
2. Documentation issue. The lifecycle is standardized, but Apple is terrible as documenting it all in one place. I found this year's "Dive into lazy stacks and scrolling with SwiftUI" WWDC video actually had a pretty good explanation, at least for the lifecycle within lazy containers.
3 and 7. Yes, Apple's tools suck pretty bad. Preview canvas is also still terrible, despite multiple attempts to improve.
4. Not something I've experienced, not sure what you mean.
5. Yeah, Apple's docs suck.
6. Not sure what you mean here either, our stuff looks pretty much the same.
You mention some examples, I have experience with lower-level stuff: terrible. Poorly documented, and actually not really working well.
IMO they should focus on improving the developer experience instead of wasting money on the joke that is Liquid Glass (even users don't like it, right?). But anyway, too late for me: I'm soooo happy that I can develop iOS apps in Kotlin now, and just endure Xcode for building and occasional debugging.
2. There’s no magic here. There is poor documentation. The biggest trick — small views, think about what values are going to trigger a refresh. Avoid cascading view refreshes.
6. You might have missed a couple big iOS releases (iOS 7 was one to remember) where many of our apps fell over in UIKit. Swift was another ‘DOA’ for YEARS with the same issues you’re making here, each new version broke the old, but here we are in a day and age where it’s the standard.
He is brute forcing his way through life and broadcasting it on YouTube.
Dunno man, Xogot is made up of almost half a million lines of code. Of those 727 files use SwiftUI, and 65 use UIKit, 119 use AppKit (I did not count the overlap, so they are not mutually exclusive).
Using GeometryReader makes it clear he is living in the past and the fact that he uses printChanges in this year without mentioning the dedicated SwiftUI instrument show a lack of curiosity on the space.
He seems to phrase it as though he has to, that he falls back because nothing else works. What would you suggest instead?
I'm only lightly familiar with both Cocoa and SwiftUI, but I have heard many nightmare stories about SwiftUI and Swift the language. I'm inclined to take his criticism seriously, and I think there's a big distinction between people who know a platform very deeply -- you are a strong expert almost everywhere you touch :) and it's clear from your comment SwiftUI works for you -- and normal developers who, you know, just want to learn a framework once and use it to get a job done. Living in the past is not necessarily bad; it's a good thing if what worked in the past worked well and still works today.
In my professional medical opinion, he is at high risk of being replaced by a year old low-end Chinese open source LLM.
But now I feel like for most apps, I should be fine with Compose Multiplatform and Kotlin Multiplatform. I don't see the point of learning SwiftUI anymore.
But is there a single UI abstraction that succeeded in affordability for newcomers while maintaining performance and solid architecture?
It is high time to solve the write-3-apps for each usecase (iOS, Android, Windows). I use MAUI on some projects but it is still not perfect.
The way forward for Apple is to open source more and more and let the Swift community build a cross-platform solution.