Hacker News new | past | comments | ask | show | jobs | submit login
SwiftUI Defaults Considered Harmful (tonsky.me)
185 points by Aqua_Geek on Feb 25, 2020 | hide | past | favorite | 132 comments

SwiftUI has defaults because nobody knew what UIKit's were supposed to be. Some of them were fiddly secret layout guides in Interface Builder, and some were accessed through the magic "-" in a VFL constraint, but overall it was very difficult to actually know how much spacing things should have. And on Apple's platforms, this matters: users know what things should look like, and if you're off you just look out of place. And if they change in the future, which they have on occasion due to new iOS versions or hardware (iPhone X, anyone?) you might end up off even if you didn't change anything in your code.

SwiftUI intentionally abstracts all of these things away from you so you don't have to deal with it, or even know about it. You're used to programming on the web? Well, the web has no standard. And anyways, people looking for magic defaults is how "8" and "44" show up seemingly randomly in iOS apps. Let the system decide for you…if you really need to override it, you can add your own explicit value.

Yea, well said. There are some awkward bits, but if I were writing an article on my first 4 months with SwiftUI it would look totally different.

There are tons of bugs, random issues, and a lack of controllable properties in areas. There’s a lack of documentation, performance, etc.

But the language, defaults, components? All wonderfully done.

In fact I’d spend years building a UI kit in React attempting to standardize on things like that, and on seeing and using SwiftUI I was constantly impressed by how well done it all feels when the language (Swift) is robust and designed to work alongside the framework.

Count me as basically optimistic, just hoping they iron out all the beta-y aspects quick!

UIKit has enough abstraction to allow not knowing the magic numbers and looking right. What with safe areas, margins and reading guides, all this has been possible for many years now.

The problem isn’t the API; it’s terrible product managers and designers, usually from the web world, who think they know better and ignore platform APIs for hard coded numbers. SwiftUI won’t save those clowns from themselves unless it completely takes control out of their hands, like WatchKit.

There are definitely a few things it does that are weird, and this article hits on a few of them.

But, I'll call special attention to the whole "adaptive padding thing" as a broader signal for something I feel that SwiftUI does very, very right and more UI frameworks need to start thinking about. Its made to design iOS apps. iOS has a design language that (1) is relatively consistent, (2) changes over time, and (3) changes across the many devices Apple supports.

In this era of many, many devices (don't just think Apple here; think any device; think VR, think TVs, etc), we need to operate at a higher layer of abstraction than most UI systems operate at. Most websites are pure garbage on 35" ultra-ultra-wide displays. It took a decade before mobile web entered the "generally useable" state it is in today. Ever tried to enable an ultra-high DPI setting on, say, Ubuntu or Windows?

All of these are getting better, but they only get better because the underlying technologies are becoming more generic.

> If I forgot to put padding between HStack elements, well, shame on me, there should be no padding! All mistakes are mine.

Wrong, and Apple has the data to prove it. When you release a poorly designed app to the App Store, the mistake is your's; your customers suffer because of it; and, it hurts the optics of application quality on the App Store, and thus Apple suffers.

This is relatively easy to draw a comparison to, say, manual memory management in C++. "If I forgot to properly bounds check a memory segment, well, shame on me, there should be no bounds checking! All mistakes are mine". Sure; and now your customers are vulnerable to hackers. You have a higher responsibility than just your Pride.

The defaults should be Safe. There should be options to override them when I feel confident I know what I'm doing (and SwiftUI has this, not the least of which being, you don't have to use SwiftUI, you can mix-and-match SwiftUI components with traditional iOS components).

Haven't we been going in the other direction in recent years?

With integrated title bars in browsers, custom css, fonts etc.. Chrome on Windows, Mac, Linux etc. always looks like chrome but not native. Similarly webpages look "exactly like the designer intended" even if it is a very bad fit for your device.

We used to do things generically, but changed to prescribing every little detail and this now breaks when our assumptions change.

We did use to do things generically, but more-or-less the wrong kind of generic.

Android is a great example of this. I don't know how things are done now, but for its first few years, they had screen size classifiers; ldpi (low dpi), mdpi, hdpi, etc.

Of course, devices got better. That set grew to ldpi, mdpi, hdpi, xhdpi, xxhpdi, and xxxhdpi. There's also tvdpi for televisions.

It was supposed to be generic. It became a mess, because they were operating at the wrong level of abstraction. But whats more; in the beginning, the `dpi` of a device was actually a consistent way to determine the screen size! I saw many apps in the day rely on this; they'd change the text sizes and paddings and even high level UI organization upon render by conditionally checking the dpi of the device. Its generic, right? Its not like I'm saying "if screen width is above 750px, render X" (cough css).

I know less about android as we approach closer to today, but I'm familiar with another problem they had concerning foldables. Android apps were never designed, from the start, to be able to respond to changes in screen size! So that required some new frameworks to be put in place, and old apps had to update.

Point being; our UIs have gotten more complex, because the problems they're solving have gotten more complex. We had HTML; a truly pure form of "generic UI design". But, it was designed for documents, not applications, so we built CSS and JS and wrote ourselves into the mess we're in today. Android had some ideas around generic UIs, but they too did not predict what people would actually be using their platform for and where technology was going.

SwiftUI is another stab at this, and maybe they'll get it right. I don't know. But, I think technology is settling a bit, and with that settling comes a greater understanding of what UI designers need from their frameworks.

>Its not like I'm saying "if screen width is above 750px, render X" (cough css).

CSS "px" units are only raw pixels on 96dpi displays. It's normalized with respect to the dpi. On higher-dpi displays, CSS "px" can refer to multiple pixels. So controlling layout based on the screen's width in "px" is fine; it won't break when someone switches to a super high dpi device.

> Android is a great example of this. I don't know how things are done now, but for its first few years, they had screen size classifiers; ldpi (low dpi), mdpi, hdpi, etc.

This example doesn't really work. Those buckets have always been primarily for image asset selection, not UI declaration/layout. It's comparable to the 1x, 2x, 3x that exists in iOS land.

Nothing has ever actually replaced those. In any UI toolkit. Vector assets finally took a chunk out of their usage, but there's still plenty of assets that are not vectors.

The density support in Android largely remains the gold standard. The only UI toolkit that actually achieved robust density independence. There's plenty broken about Android's UI toolkit, just this isn't one of them.

Yeah, that was a misprint on my part; I should have referred to them as density classifiers, which is what they are. My brain got jumbled because my broader point came later on, in how there was a time years ago when many apps were elying on them as a signal for screen size, to the point where I saw apps place layout files in a specific mdpi or xxhdpi folder.

Of course, today, I'm sure the Android landscape is more mature and different; I have less context about the thinking around a modern android app today.

Case in point: WhatsApp TestFlight betas recently gained support for dark mode, because they decided to do custom UI (and, honestly, not a terrible one) and it took ages for them to fix it up to support dark mode.

Meanwhile, many native-iOS developers had dark mode support on day one, because they stuck closer to iOS conventions and didn't do as much custom UI.

Frankly I don't know what in the world you're talking about. WhatsApp is one of the best examples of a native iOS UI implementation. Looking at the app now, it clearly uses very lightly customized native UITabBarController, UINavigationController, UINavigationBarItem, UITableView, etc. The only examples of custom-built UI elements in WhatsApp only come from stuff like the camera view and the messages view. These are areas where Apple doesn't really provide ready-made UI classes in the first place.

The point isn’t that adaptative spacing does a good job most of the time, it’s that it’s doing things it isn’t telling you about in code and you “just need to know” for when it isn’t doing a good job.

Think about having to remember UI padding voodoo the couple days after you back from a vacation.

The UIkit shouldn’t try and hide language normal commas, it shouldn’t try and imply “smart” or “magic” padding.

Similarly, We've all seen incomprehensible ten-thousand line CSS styles sheets, with layers of inheritance, where you're forced to grep through to find that one line on some ancestral class that controls the left padding for every h1 on the site... except this specific one, which I guess is using !important on its own class? Damn it.

So, what'll it be? We're talking about inherent complexity. Should it be application specific? Or should the platform take a stance on the Right Way? If we have a rule that holds in 95% of cases, embedding that rule into the platform itself does make sense, as long as you can escape hatch out in those 5% of cases it doesn't hold. It reduces the complexity developers have to hold in their head. Its no longer "Oh, yeah, I need padding on that, how much? 4 pixels I guess. Is that standard? Wait, no, i think we moved to 8px recently. Or, wait did we move this to 'em'?". Its just "I need padding. I'm adding padding. On to the next thing."

Your company isn't special. The problems we're each solving are more alike each other than not. Embrace the magic. Learn it. It'll make your life easier, and your software better.

>"Oh, yeah, I need padding on that, how much? 4 pixels I guess. Is that standard? Wait, no, i think we moved to 8px recently. Or, wait did we move this to 'em'?"

I'm not sure how the magic/JustUsuallyWorks/ solution fixes this issue. If the argument is people need to remember things, and SwiftUI takes that away and just puts in what an algorithm thinks is right, that's probably going to be pretty generic design for the final product.

You're right but it's a tradeoff I guess. It seems like they want to optimise for developers building half decent looking apps with adaptive UIs across their platforms with less effort.

This website's background color is considered harmful, and "considered harmful" essays are considered harmful.

Site is also non-responsive with <meta name="viewport" content="width=640" />, looks horrifying on the 12.9’’ iPad Pro even without taking color scheme into account. I know complaining about blog design is out of scope, but if @tonsky is reading this thread, please consider fixing your meta viewport tag.

> I hope you have a wide enough monitor to read this.

Perhaps they're merely unaware of how their website looks?

Yeah, I did think it was amusing reading that on my 27" 2550px wide monitor monitor that the site formatted it so narrowly. https://i.imgur.com/VG31Kpj.png

For body copy that line length is pretty much ideal (for readability), but the code blocks could definitely benefit from being as wide as possible...

Yeah, the reading experience was pretty comfortable. Just thought it was amusing that the author hoped I had a big monitor when the author constrains the code blocks to such a narrow width.

This part also tripped me up since I _was_ on a large monitor but the width was tiny.

That refers to a <pre> block with no carriage returns, which ordinarily wouldn't wrap.

Or they use some special monospace font where 157 characters at 16px could somehow fit into a 544px wide column (well, that still got nothing to do with monitor width, though).

I always see people complain about the narrowness of Medium and think they're overreacting, but this site is pretty extreme. I could fit 3 of these side-by-side across my 13" MacBook Pro's screen.

> I know complaining about blog design is out of scope

In this case, considering the topic, such a complaint is really warranted. A set of sensible defaults for that blog would have made it more readable — the blog design is pretty much a rebuttal of the content.

I changed the CSS before reading

After reading this I agree that SwiftUI terrible. I still don't get why it's considered "harmful" though.

This is basically a clickbait title at this point. After a now-famous CS letter by Dijkstra, "Go To Statement Considered Harmful"[1], the title format expanded dramatically. I'm personally a large fan of Meyer's '"Considered Harmful" Essays Considered Harmful'[2] as a explanation and satire of the genre. Wikipedia also has a decent summary[3].

1: https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.p... 2: https://meyerweb.com/eric/comment/chech.html 3: https://en.wikipedia.org/wiki/Considered_harmful

This letter was also a classic example of how writers don't always choose titles, editors do.

Edsger Dijkstra's original title was "A Case Against the Goto Statement". Niklaus Wirth was editor of the Communications of the ACM (Association for Computing Machinery) at the time and changed the title to the now infamous "Go To Statement Considered Harmful".

Explaining "Considered Harmful" Essays Considered Harmful

The background made me think Flux turned on spontaneously.

Agreed. Going from a solarized-themed HN to that link was simply painful.

Just when I thought Lisp had been ransacked for every last feature that language designers were willing to steal, the "War on commas" pops up -- complete with discussion of the essential differences might exist between "(" and "{", the pain of needing another way to say "if", and the lack of support for the rest of the language.

And the last couple interesting Swift libraries I saw had .gyb files and #if directives.

Apple tried really hard to make a fully static language that was visually elegant (and looked like C), but in the end we need so many dynamic features that what we ended up with seems much more complex than just having had well-designed macros from the start.

The cynic in me suspects that they know this would be worse, but has the advantage that only Apple can add such features, not the common programmer. OTOH, the cynic in me knows that staying far away from Lisp is par for the course, and every new language needs their code to look like an example from the designer's tattered copy of "K&R".

At least they managed to drop C-style for-loops in a mainstream language, so next time a company decides to design a new language, we can hopefully start there. I predict we're about 3 generations of corporate languages away from seeing macros get "invented" again.

many modern languages have macros: rust, crystal, elixir, nim not very corporate though, but getting there? with rust(mozilla a bit and others)

Java and .NET languages also have them, although a bit cumbersome via attributes, compiler plugins and on .NET's case, expression trees.

Maybe Apple should embrace a Dylan variant again.

I really don't think this is a good criticism of SwiftUI.

The author is confused about the whole approach to SwiftUI and spends a lot of words complaining about issues arising out of that confusion. E.g., SwiftUI doesn't use Swift's DSL capability to avoid commas. It uses it to have a declarative DSL integrated into Swift programs. You could argue about the entire approach, but instead the author complains about commas and ifs. The things about the ifs and other potential control flow constructs makes it clear that the author doesn't get what a declarative approach really means.

Likewise, the section about "wraps" where the author feels the SwiftUI API is inconsistent because stacks "wrap" and padding "wraps" so they should use the same syntax. But I think that's just a misunderstanding of the author's. "wrapping" isn't a fundamental concept of SwiftUI so there's no particular reason for the API to be organized around it. (I would say stacks arrange a list of views and padding pads a view. Also, bold() operates on Text and returns Text because Text holds styled text and bolded Text is still Text. padding operates on any View and returns some View. The types flow naturally from the problem domain, so that's good.)

Also the conclusion: "The solution…is to be dumb and explicit!" That's really asking for a completely different framework. It seems a little off to criticism SwiftUI for not being what it was never intended to be.

I think there is good criticism in here, though. SwiftUI introduces a LOT of patterns, concepts, many of which will not already be familiar to many developers. It's concise and reads pretty intuitively, but many developers won't get far before hitting a lot of new stuff... that means steep learning curves and confusion, like the author. I don't know if that makes it bad, but it's certainly anyone consider using it needs to be aware of.

The author is also the author of Clojure/script libraries Rum snd Datascript. He knows what declarative means very well.

Swift UI creates a mess of special cases pretending to be declarative, and does a poor job of it.

He's suggesting he ought to be able to use imperative Swift control flow constructs in the declarative SwiftUI DSL. I suppose I can't really know exactly what his confusion is, but that just doesn't make sense.

It does make sense. Because SwiftUI creates special constructs for regular language features (if, foreach) despite those features, you know, being available in the language.

It doesn’t make sense because SwiftUI is a declarative language. I understand the confusion, since it uses Swift’s DSL feature and is tightly integrated with Swift, but it is distinct and has it’s own design that isn’t directly compatible with Swift’s imperative control flow constructs.

Now, you can argue that Apple should have created a new imperative Swift-integrated UI framework, and if they had, it would be a good criticism if all the normal Swift control-flow mechanisms weren’t available natively. But the author and you aren’t objecting to SwiftUI’s declarative nature.

BTW, If you manage to map all the kinds of loops, breaks, etc, into SwiftUI it isn’t declarative anymore. You’ve managed to go back from describing the UI in terms of “what” (declarative) to “how” (imperative).

Since the author expresses approval of the declarative nature of SwiftUI and complains about it, I know he’s confused.

No. I, and the author, argue that nothing prevents Swift from having declarative foreach/if.

SwiftUI already introduces severely underdesigned awkward structures to replicate existing behavior, and it shouldn't.

SwiftUI's ForEach and If are ugly unnecessary hacks that replicate existing behavior and raise the question: why aren't other constructs there?

I’m guessing the magic layout things are intentional because SwiftUI is designed to make it easy to have one app feel native on iPhone, iPad, Apple Watch, Mac and AppleTV, which all have their own design language and ergonomics.

As long as it provides ways to override defaults and take full control where needed, this seems reasonable. I’m guessing you can drop a Metal view into your SwiftUI app, so quit complaining :)

Exactly, if you just want to bang something out that looks like an "apple app" across all those devices I think the auto spacing and sizing stuff works pretty well. You can always tighten it up and override it later.

I was really excited about SwiftUI after having done a lot of React development recently. The declarative style is so much nicer than the MVC/procedural code that regular UIKit code becomes.

After 30 minutes of updating Xcode I was able to start writing SwiftUI code. Then another 2 hours upgrading our Swift project to the latest version of Swift. I googled for documentation, found barely anything and the code samples on developer.apple.com were already outdated. I finally got something up and running, but _nothing_ in the semantics worked as expected. Getting a button to render nicely was insanely complex (which view should have the background color? font? trying different things didn't work at all). Oh and recompiling took a minimum of 30 seconds each time.

All this prompted me to finally give react-native a try. In under 15 minutes I had a working example. After making a change I saved the file, alt-tabbed to the simulator and the changes were already applied. And it works instantly on Android, I can try it out on my phone using expo without any hassle.

I just can't comprehend if and how Apple will catch up with that experience?

> ... after having done a lot of React development recently ... All this prompted me to finally give react-native a try. In under 15 minutes I had a working example.

The fact that you, a React developer with lots of experience with React were able to come up to speed vastly quicker on React Native shouldn't be surprising, that's a feature of the platform. You are the exact sort of person React Native was designed to make productive.

Of course you struggled, to pick up Swift UI, you needed to learn a new, vastly different language, and a new DSL that sits atop that language.

Even with good documentation and years of community expertise built up, this would have been an uphill comparison, but SwiftUI is relatively new—essentially in beta—there is very community around it and as you noticed, very little documentation... all of these last issues are pretty well known. All of them take time to overcome.

I'm not sure if SwiftUI is going to be the next big thing or not, but your comparison is a bit lopsided here.

Sorry if it wasn't clear enough. I'm by no means a React-developer with lots of React experience. I'd say I have more iOS-development experience than React. The app I wanted to port is already fully written in Swift. I've written and launched a couple of apps in Swift over the years, and also a couple of apps in Objective-c.

Fair enough.

I think time is the big decider here. Swift is new and given Apple's relatively slow update cycle (annually versus quarterly or more often for open source projects), it'll be a few years before SwiftUI really matures and (hopefully) a community builds up around it.

This year's Apple Dev Conference (If it happens) should push things forward and hopefully increase the quality and quantity of documentation at the least.

I suspect Apple knows the developer experience for Swift is terrible (even if the Apple developer community at large is in mass denial about this).

The number 2 item on Swift Core Teams goals for Swift 6 is "Create a fantastic development experience". See: https://forums.swift.org/t/on-the-road-to-swift-6/32862

Whether anyone at Apple cares about documentation any more is another matter. A really sad state of affairs, because once upon a time, Apple had some of the best documentation out there. Of course, that was when they actively needed to court a developer community, and couldn't just announce something half-baked at WWDC and get mass adoption from enthusiastic developers.

I don't know, maybe some of the die hards are in denial. I really enjoy the language and the platforms but I'd readily admit it's pretty far behind in terms of DX. I think at this point Apple is going to have to make this a really big priority if they want to remain relevant and it's going to take a lot of effort on their part.

While I certainly can't speak for all diehards, I hear a lot of complaints about the state of Apple's documentation from long-time developers these days. (In my experience, the true Apple diehards are often very critical of the company, but they tend to have specific trenchant critiques.)

Even iOS programming communities will admit you're brave for using SwiftUI right now. It's brand new, has a lot of issues like being completely unable to show you a coherent type-error message (like if you have an error inside a ForEach view).

It's just cutting edge tech.

”after having done a lot of React development recently […] All this prompted me to finally give react-native a try. In under 15 minutes I had a working example“

I agree SwiftUI is poorly documented and (from what others say), probably, not quite production ready, but I also guess that comparison is a bit unfair. Or are react and react-native completely different beasts?

I'm not a die-hard follower of Apple developer news, but it being released in June 2019 made it feel at least somewhat mature to try out. There's nothing AFAICS on the SwiftUI documention mentioning that it's not quite production ready.

> Or are react and react-native completely different beasts?

The language is the same, and the core concepts are the same, but the SDK's are completely different. You are using different build tools, different API's, different platforms. It's not HTML-in-JS. So a React developer is not going to be fluent in react-native by default.

> Oh and recompiling took a minimum of 30 seconds each time.

For a simple hello world SwiftUI app? I just checked a project I had open in xcode and it recompiled in under 1s. Thats on a mid range 2013 MBP.

> After making a change I saved the file, alt-tabbed to the simulator and the changes were already applied.

I guess Apple is aiming to get something like this experience through previews, which are a little broken right now.

Edit: formatting

Sorry if I wasn't being clear. We have an iOS app and my plan was to try out migrating an existing Viewcontroller to SwiftUI (the login screen).

I’m a 10 years ios developer, and i also gave up tryin to write a small app in swiftui after having tried for an hour. It’s just impossible with the current level of documentation.

I think the picture is darker than what you’re describing : as long as apple doesn’t provide a real cross-platform environment (like google does with flutter, or facebook with react) then it doesn’t really matter what they end up doing with swift UI.

My intuition is that they know it, and that they’re working on something pretty big in that field, maybe as an improved , cross-platform version of swift ui. That would explain the lack of documentation (why document something that’s only a temporary version of a tech). But maybe i’m dreaming and everybody at apple live in its own bubble...

While I don't yet have great confidence in my mental model of SwiftUI's type system, my understanding is that the DSL builders exist for more reasons than just to eliminate commas.

The new Function Builder and `some` return type features of Swift allow you to return a complex, nested type describing not just that it's a View but rather also all the structure within.

This means that at runtime you can have a (non-erased!) type describing the contents of your `var body` like this:

    Button<Group<_ConditionalContent<Text, Image>>>
This particular body displays a Text if a state boolean is true, and an image if not.

Super interesting - and having types this descriptive can potentially enable a host of interesting features and optimizations. For example, across evaluations of your UI SwiftUI needs to track the identity (and location in your view graph) of all of your views, in order to keep their state, bindings, and other stuff that needs to remain consistent across time. The position if your view in a type hierarchy is the default way SwiftUI does so. This starts to blur the line between code and the type system, which I think the Functional Programming folks have been exploring for years.

One more nitpick: the use of View Modifiers on children noticed by parents (like the `navigationBarTitle` example he uses (as discussed in the "Child Privacy Invasion" section), is to allow for children to specify metadata that the parent might care about. This is actually pretty nice, because then you can nicely compose together the various parts of your app without having to spread around the configuration for your tab bars and such (which is a bit messy in UIKit).

edit: formatting. I always trip up with it on HN due to the lack of a Preview feature.

> One more nitpick: the use of View Modifiers on children noticed by parents (like the `navigationBarTitle` example he uses (as discussed in the "Child Privacy Invasion" section), is to allow for children to specify metadata that the parent might care about. This is actually pretty nice, because then you can nicely compose together the various parts of your app without having to spread around the configuration for your tab bars and such (which is a bit messy in UIKit).

I wouldn't say it's too messy in UIKit but I agree with the motivation. To add some more context here's how you configure the title of the navigation bar in UIKit

    navigationItem.title = "My Title"
    navigationItem.largeTitleDisplayMode = .always
This does not happen in the class that renders the navigation bar(UINavigationController) nor does it happen in the navigation bar view itself(UINavigationBar) it happens in the view controller that is currently on screen and is the "active" child of UINavigationController.

Observing the launch of SwiftUI as a bystander (I'm not developing for any Apple platform), it seems that people are very excited about SwiftUI, but also get burned by it a lot. This is mostly Apple's fault by releasing this framework without any caveats. But the framework is more like an early alpha, not to be used in production. Tooling is not yet ready, documentation is not yet ready, heck even Swift –the language and compiler– aren't even ready yet. Apple should've put a big warning notice on any SwiftUI related website to set the correct expectations.

I agree for the most part however I have put a simple app in the store with it and it works fine, it's usable for small apps. I had to wrap a few UIKit elements and a few other workarounds that I can't think of right now. But overall I'm happy they released it early and can benefit from the communities feedback and usage rather than building the whole thing in secret and releasing something finished that we might not even want. I hope that this is the beginning of them improving DX on their platforms as they have a lot of catching up to do to be competitive with other platforms.

Yeah, my sentiments exactly. I'm in the process of finishing a small app for a client, and it's been a blast. As you said, a number of workarounds are necessary due to the fact that UIKit is so rich, and SwiftUI is rather sparse at the moment.

However the fact that it's so easy to build new UI components, at this phase partly makes up for it.

Actually this a very common practice for Apple and well known among seasoned devs. Apple’s shiny new things don’t really belong in production apps until a few major versions in. In my decade of iOS development experience prevailing wisdom has been that nothing has ever worked until at least a few major versions in and don’t belong in production apps unless you really love rewriting your entire codebase.

Good rule of thumb is an application usually needs to support at least one prior major iOS version and SwiftUI is only available on 13. Don’t know current adoption numbers but I believe there is still a significant % of users still on 12.

Just don’t be surprised when SwiftUI apps require major refactoring to work on iOS 14.

I haven’t even touched SwiftUI yet as I’m orders of magnitude more productive with RxSwift and every single realworld-ish example implementation I’ve seen makes my eyes bleed.

Wouldn't Combine be the official competitor of RxSwift?

In the App Store that's called Sherlocking ;)


Like I said, RxSwift is ready, SwiftUI/Combine isn't.

As someone who is a bit more involved in iOS development, I am also standing on the sidelines. Mainly because any apps that I am developing for, I can still keep on using NS Layout Anchors that work wonderfully. One of the biggest reasons I have decided not touch it is because of problems like these, until there is a v2 or v3 for swiftUI, its just not worth it to include it in any projects. (imho)

You are not developing for any Apple platform. And then later you state that the framework is more like an early alpha, not to be used in production.

On what basis do you make that rather bold statement?

I tried out SwiftUI a couple of months ago and it was buggy even when sticking to the standard Navigation components..

But now it seems like a lot of problems have been solved


> even when sticking to the standard Navigation components.

The standard navigation components have always been the buggiest part of UIKit. Don't even get me started on how UISearchController and UINavigationController interact on iOS 13…I have an app that's been sitting on the back burner, with full dark mode support, but unreleased for over six months because I haven't taken the time to figure out why the search bar decides it wants to be above the large title.

Didn’t know this! Am very much an amateur with iOS development and thought that sticking with the Swift “happy path” would’ve been a good idea

It's gotten better, it will probably work if you're not doing anything complicated. My view is set up from a five-year old storyboard and is dual UINavigationViews with UISearchControllers inside a UISplitView inside a UITabViewController :/ I'd still suggest sticking to the happy path, the other ones are even worse…

Do you have more examples than just that single one?

I ask, because I've encountered a number of situations where I figured it's a bug, when in fact it was my lack of understanding this new framework.

I had this issue in the simulator but on my phone it seems fine. Not ideal obviously but it does work, I released a simple app with it earlier this year.

OMG you cannot know how many times some SwiftUI thing has worked fine on my iPhone but not on the simulator … that was simulating my iPhone model running my iOS version.

> Some things are probably just plain mistakes (very funny though). E.g. NavigationView takes its properties not from its constructor or via modifiers, but instead from the properties of its first child. WHY?

This sounds like it's just inheriting the default iOS behaviour? The current ViewController sets the Navigation View's properties.

I haven't touched SwiftUI yet, but I'd imagine the existing NavigationController setup still exists within the SwiftUI framework, and this weirdness exists due to legacy reasons essentially.

Reading through the syntax changes they made makes me really appreciate the decisions made around JSX and how that works, syntactically. It's just javascript, and none of these weird constructs need to be added into some DSL to support it. There's the reasonably minimal html-ish syntax, then "escape to javascript" to add in conditionals or loops or whatever.

I wonder if there was (or still is) a way to do something similar for Swift and SwiftUI.

It’s hard to claim that JSX is more “just JavaScript” than SwiftUI. If anything I’d say it’s the opposite.

Swift evolved the language hand in hand with SwiftUI so everything you see is standard there.

And in my humble opinion they did a knockout job. And this is coming from someone whose spent a ton of time evangelizing React.

SwiftUI is far more beautiful, pleasant to write, and well thought out. It does have a couple awkward points but it’s not the “DSL” or it’s defaults (it’s just Swift) which is fine, it’s all on the dev tooling, performance, debugging, random bugs, and error messaging side of things (ie, maturity).

> It’s hard to claim that JSX is more “just JavaScript” than SwiftUI. If anything I’d say it’s the opposite.

Yeah, that's fair. What I saw was that SwiftUI added special constructs to this DSL for if and ForEach statements, something which just isn't needed in JSX because it 'escapes' to JS fairly well.

Definitely think they did a pretty decent job of it - I couldn't have done better (and I can't judge whether a better job could have been done, I know next to nothing about Swift, hence my initial question), but it does strike me as unfortunate that they needed to specially re-create basic language features.

You can map over things much like react, the ForEach is not quite as clean but you can still write your .map function in the body function and then just pass it where you want. I think the strict typed nature makes some of these things a little less flexible but it wins in many other categories.

I’d say give it a twist! If you like React you’ll like it, just has different trade offs.

Surely JSX is ... well it's something that looks a lot like XML, hence the name. It's not just JavaScript, is it? It's pretty much the definition of embedding a DSL.

I've not used SwiftUI but I've used TornadoFX which is similar, but with Kotlin instead of Swift. There's no weird syntax or DSLs (even though they call it that). It's all just functions and lambdas, so the language is always there and the syntax is always consistent with what you use elsewhere. It's not like React/JSX where UI code syntactically looks different.

JSX is 'just' an XML-like syntactic sugar for making nesting function calls nicer in Javascript. Yes, its a DSL, but it keeps the "domain" extremely small and it transpiles in a very straightforward way down plain javascript

      <Text weight="bold">madeofpalk</Text>
      <Image src={profilePic} />
    // is syntactic sugar for
    React.createElement(Container, null,
      React.createElement(Text, { weight: "bold" }, "madeofpalk"),
      React.createElement(Image, { src: profilePic })
Whenever you need 'logic', you just escape out to javascript with braces

      { isVerified ? <Tick /> : null }
      <Text weight="bold">madeofpalk</Text>
      <Image src={profilePic} />
JSX has no conditional syntax, no ternaries or any extra constructs apart from how to nest children. This is I think a simplicity that would have been nicer to see in SwiftUI.

I guess I'm not sure why this is better than the Kotlin/Tornado/SwiftUI approach of allowing you to move a lambda in the last parameter visually out of the function. So:

    container {
        text(weight = "bold") { "madeofpalk" }
        image(src = profilePic)
It seems more logical and consistent with the rest of the language. The only reason for the HTML-like syntax is JavaScript's tight connection to the web, after all.

I apologise for not being clear, but the point I'm trying to make is not around the angle bracket syntax, but with how light the DSL is and for any sort of logic syntax, you just escape back to Javascript.

JSX does not have conditionals or loops in its syntax. SwiftUI does.

Interesting that in PHP days, mixing logic and markup was taboo, and now it's all the rage.

Very specifically, this is not mixing "logic and markup" in the way that was taboo.

This is all UI logic. Should a button be displayed or not. How large should this rectangle be. React encourages you to place that logic close to where it's used so it's easier to understand.

The line React devs has used is when people look at JSX and shout "separation of concerns", what they're really grasping at is "separation of languages".

So it's reinventing PHP and Java Server Pages?

I’d say it’s a re-creation of what E4X brought to ECMAscript / Actionscript. Saying JSX is similar to PHP / JSP is a gross mischaracterization imho.

It's syntax sugar which does directly translate into JS though - you could actually just write the original/underlying code.


    <Foo var={'a'}>
        <Bar />
Becomes something like:

    React.createElement(Foo, { var: 'a' }, React.createElement(Bar))
It all boils down to

    React.createElement(component, props, ...children)

.nib & .storyboard files are XML based so one could conceivably write a dsl to represent interface builder xml in swift if one doesn't already exist.

SwiftUI is a definite move away from interface builder.

Those two statements contradict somehow.

Why wouldn’t Apple be able to switch XML with a Swift DSL and keep the Interface Builder UI intact after most of the biggest SwiftUI issues get fixed?

This is a very myopic view of UI development. The library is built to give you sane, well designed defaults that is lay together well when following the HIG, and which you should rarely attempt to override. Case in point, HStack, whose sole purpose is to stack items horizontally with proper spacing and is quite hard to achieve correctly on the web. If you want “dumb and explicit” why use a UI kit?

> When fixing broken layout, it is always easier to add stuff that you forgot than removing stuff that your framework did for you and you that can’t see.

This paragraph reminded me of this old Jargon File koan:


In the days when Sussman was a novice, Minsky once came to him as he sat hacking at the PDP-6.

“What are you doing?”, asked Minsky.

“I am training a randomly wired neural net to play Tic-Tac-Toe” Sussman replied.

“Why is the net wired randomly?”, asked Minsky.

“I do not want it to have any preconceptions of how to play”, Sussman said.

Minsky then shut his eyes.

“Why do you close your eyes?”, Sussman asked his teacher.

“So that the room will be empty.”

At that moment, Sussman was enlightened.

I've never understood this one. Initialized randomly and then trained is accurate; Minsky is the one who comes off as ignorant, when the last line is supposed to indicate the opposite.

That's not ignorant on his part, it's just a silly analogy to get the point across; and I think you're missing the point by thinking of what happens after the network is trained; the point made is about the initial state of the network, not the outcome.

The neural network will have preconceptions on how to play no matter how, even if you wire them randomly; the difference of making them random is that you'll have no idea what those preconceptions are, not that they don't exist. The original story on which the koan is based might make it clearer.

[1] https://simple.wikipedia.org/wiki/Hacker_koan#Uncarved_block

If you still want this to be about the final state, the point would be that, if the training process works well, it shouldn't make any difference whether the net was wired randomly or orderly.

The “X considered harmful” trope for deliberately strident technical screeds that quibble about what are mainly niche concerns has tired me out.

“‘X considered harmful’ considered harmful”, I guess.

You’re going to love this essay by Eric Meyers.


Now I await “Comments linking to the ‘considered harmful essays considered harmful’ essay on ‘x considered harmful’ discussions considered harmful”.

I think everything after the first gripe is a fair point, but I don't get what the problem is with the first code chunks... it seems like the author is saying "this is weird to me, and I don't like that," but I have no idea how else it'd work properly.

For example, explicitly defining out function arguments is exactly what Scala does for function, check out this bad mofo, defining a function with 22 arguments (that I fell in love with years ago): https://www.scala-lang.org/api/current/scala/Function22.html

Why'd I fall in love with it? Because it makes sense, that's how it should work right? I don't see how defining out 10 items explicitly; so, that each can have it's own type, is a problem. It's pretty damn nice they did it out to ten arguments, if you want more, extend the object... /shrug

If you used a list instead, e.g. `T[A]` you'd take a hot-fat erasure-shit on the type information of each item in the list (or at least you would last time I used Swift extensively)... this way you keep that type information around.

P.S. To be honest, explicitly defining things out like that can give you HUGE wins in languages like Swift because you give the compiler so much more information. It just doesn't usually pop onto most folks radar because it looks obtuse... with most modern code editors though it's easy enough to write in a couple minutes, if there's no macro system.

I really don't agree with most of this post but I do find the function builder[0] feature that was introduced to support SwiftUI fairly overkill. I don't fully understand why they didn't use a lighter abstraction based on arrays and normal return values like React does instead of adding all this "magic", maybe there's a really good reason that I am not seeing.

All the other "magic" and defaults are excellent ideas because they encode Apple's Human Interface Guidelines[1] straight into the framework which helps you create apps for the different Apple platforms that will fit in and feel at home. With a web or React Native/Flutter/Cordova/... context this might seem jarring but the whole point is that an app it shouldn't be a completely free form canvas and the frameworks should make it easy to build a best in class HIG compliant Apple app.

0: https://www.swiftbysundell.com/articles/the-swift-51-feature...

1: https://developer.apple.com/design/human-interface-guideline...

> I mean, the only difference before the two is whether you have to put a comma between elements or not.

Personally, I vastly prefer minimizing punctuation in code. Most punctuation like this only lends itself to creating places where additional errors and bugs can creep in. Listing elements on separate lines gives you the separation needed so it's clear it's a list of things, the comma at the end of the line is needless.

> All because someone in charge of API design was afraid of lists and had more power than someone in charge of Swift language.

I suspect the people in charge of designing the Swift language have a similar aversion to needless punctuation in the language. They made a point of calling out the lack of a semi-colon in the original Swift launch announcement. This isn't some API designer pushing the issue, it's part of the philosophy of the language.

I recently started a SwiftUI project and this is a very accurate take based on my experience.

How I spend my time in SwiftUI: 1. Wondering how I can get some conditional logic. Coming from React, this is a major issue that needs to be addressed. 2. Figuring out where and what the error actually is. 3. Restarting Xcode for my view to magically start working again.

The two-way data binding is a blessing and a curse. I like React's method of passing callback functions to keep the state logic separated. This comes up with me when working with sheets.

I see the potential. I like having an all-in-one experience that IDE + framework integration provides but the poor defaults and breaking bugs really make me question the execution.

I'm in no hurry to start using SwiftUI. I'm giving it another year.

That doesn't mean that I don't like it. I think it's a great idea. It's just having a hard time clambering out of the bassinet.

> It's just having a hard time clambering out of the bassinet

What are the reasons for you to have this opinion?

Mostly the limited uptake (I anticipated that), and the maturity of the tools. I despise IB/Storyboard Editor, but it gives some serious control over a lot of stuff.

I don’t mind doing programmatic tweaking, but on my machine, at least, I don’t get very reliable previewing. I have to run the app to get an idea of how my tweaks are working (to be fair, IBE is similar, but the preview is somewhat more reliable).

I really want this to work. I’m glad to see KVO getting some love on iOS.

Limited uptake by developers you mean? How do you determine that?

I had two instances where the preview turned out to be a hassle (crashing, or hard to get it to work).

First was a test project with Core Data. It was a hassle to set up the preview. So much so, that I often skipped it.

Second instance was crashing; I'd created a View but the layout was based on something in UserDefaults, and I forgot about that. So when I created another view that incorporated that first view, I got crashes. So bad, in fact, that a restart of Xcode didn't help. I had to close Xcode, then on the commandline, find and kill the daemon responsible for previews.

Were you able to point to causes of the unreliable previewing in your case?

Aw..heck. I'm not gonna get into back-and-forth.

I will say that I have been developing Apple software for 34 years, so I tend to be a little on the.."hard-boiled cynic" side.

I have taken OpenDoc and QuickDraw GX classes, because they were "The Next Big Thing."

I also busted my butt, making sure that my apps were "Copeland-ready" (Darn it, now I have to do fifty push-ups).

I've learned that it's a good idea to stand back a little, and let the eager beavers soak up the bullets.

I love Apple (see "34 years," above), but they are absolute Charisma 18 hype machine masters.

Leaning towards the careful end of the spectrum, I can respect that. Especially once you're fast with UIKit, and Auto Layout. And Auto Layout kinda proves your last point; there's absolutely nothing "auto" about it.

Auto Layout is a nightmare. I won't be sad to see the back of it.

It took me a couple of years to figure out how to use it properly.

Like I said, we're on the right track, and I doubt that Apple will let this fall by the wayside. I think they were planning this at about the same time that they started dreaming up Swift.

> I hope you have a wide enough monitor to read this. Not only does this seem ad-hoc and unpretty, but it also doesn’t allow you to put more than 10 elements in a container! All because someone in charge of API design was afraid of lists and had more power than someone in charge of Swift language.

This explanation doesn't sound right to me coming from other statically typed languages where you're stuck either using codegen or arity hardcoding. Currying also gives a nice solution where your DSL simply builds up a function A->B->C->...

Hard-coding each level of arity is done so that your generics keep upstream type knowledge.

Here's an example in Elm, though it has to keep renaming the function due to lack of arity overloading.


You can't use variadic functions because then you function doesn't even know how many arguments it has at compile time much less any specifics about them.

That Swift doesn't require commas between closure returns seems like a different point.

You'd still need this solution even if you were just spitting out generic TupleView<(View, View)>, TupleView<(View, View, View)>, etc.

Unless, of course, you don't actually care about type info the same way you don't care how many arguments are passed to a variadic max(1, 4, 66) function.

Another comment says there will be a variadic viewbuilder function once Swift gets variadic generic functions which will still throw away type info, so this seems to be the case. Still, I don't see the relationship with commas.

Just to point something out: his first complaint is over needing to have up to 10 generics, this will be going away with variadic ViewBuilders that should be coming soon, towards swift 6 perhaps. And will also remove the limit for number of children. This is mostly a limitation in swift generics, not swiftui it self

Honestly, just use UIKit. SwiftUI is a bolt-on framework on top of UIKit to provide a React-like experience for web devs so they won’t rage too much when Apple inevitably bans ReactNative and Flutter.

SwiftUI is raising the abstraction layer and aiming to provide something much more productive than what UIKit currently offers. You've framed your comment as if web developers are cargo-culters who only know how to use React. The web has already experimented with classic MVC approaches (backbone etc.) and moved beyond it. Android's Compose is taking a similar approach, as is Flutter which as far as I can tell is not necessarily aimed at web developers. Also why would Apple ban React Native and Flutter?

I don't believe they'll ban it. I do believe they'll increase friction to the point that it becomes a huge pain to use either for anything but prototyping.

I can't see really why they care that much how the app is written, if it adhears to the app store guidelines and makes them money then I doubt they're that interested in banning it or increasing friction. Nearly all the current top selling iOS games are likely written in Unity and I can't see them banning that.

Platform coherence, but also look & feel come to my mind.

While the guidelines are what the word says, vague guidelines with a lot of room for interpretation, they don’t necessarily dictate any details. When you look at it from a more technical point of view, it’s harder to do something nonconforming with Apple’s frameworks than with 3rd party alternatives.

Games are a different thing. They are more like their own operating system within iOS and usually have their own quirks (to make them playful).

Would it be possible to wrap SwiftUI such that we don't have to use that DSL, don't have that 10 child limit (how many hours wasted figuring that one out?), and don't have bizarre non-localized error messages?

My guess is the answer is no because SwiftUI builds view hierarchies using parameterized types, so you're always stuck with `some View` and the associated complexity.

Is SwiftUI only compatible with the newest iOS versions? Will using SwiftUI mean only people running iOS 13+ can use it?


That said, current iOS 13 adoption rate is already at 93%...


I just checked <https://mixpanel.com/trends/#report/ios_13> and it shows iOS at 85%.

About a month ago, I started releasing versions of our app on iOS 13 in TestFlight (I wanted to use the new SF Symbols) only to discover there are a lot of iPhone6 models out there. My first reaction, was "c'mon, that's a 6 year old iPhone, time to move on!" until I found that Apple kept selling the 6 all the way through 2017. A lot of "budget" buyers purchased iPhone 6's up through that period. So I've come to be skeptical about these claims of adoption rate. I subsequently reverted to iOS 12. :(

I asked this question because I still use an iPhone 6, and can't update past iOS 12. My MacBook Pro from 2013 can upgrade to Catalina and handle developing with it, but I'd rather have a compatible device than rely on the phone simulators.

Yeah but it does mean that older devices become useless. For example, I have an iPhone 6 that I let my kid use, and he won't be able to run any of these new apps.

I also have an older Ipod touch, I was trying to find an audiobook player to use it to listen to books, I couldn't find any that was compatible.

My most popular app supports iOS 9, so it's not being rewritten anytime soon…

How many people are using iOS 9?

Very few, I’d expect, but for my target audience (students) I’d expect it to be biased a but more in that direction. It’s not a huge amount of extra work (just condition all the new code) so I’ve just keeping the requirements the same.

> I’d expect it to be biased a but more in that direction.

You should be able to get pretty exact numbers for your app in AppStore Connect. The results might surprise you.

Typically we have way faster adoption in our apps than the trend. YMMV.

About 90% iOS 13, 7% iOS 12, and a fraction of a percent for the remaining. I guess that's better than I expected…

Interesting how most of his points are exactly how Flutter is implemented. For example the trailing commas, and no assumed defaults.

Things with "considered harmful" in the title should be considered harmful.

Considered Harmful essays considered harmful: https://meyerweb.com/eric/comment/chech.html

I am not sure it's a good idea to take advice from someone that picks such a background color

To the person who wrote this, I would suggest SwiftUI is not for you. Please just go back to writing Objective-C or learn some good ol' UIKit. You can then have full control over whatever color you want your buttons to show up as, and where to have them show up, and with whatever padding you like, and as a bonus you can use commas and all kinds of great additional syntax all over the place. (I think what SwiftUI is for, has largely flown over your head).swiftly

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact