Perhaps they're merely unaware of how their website looks?
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.
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
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?
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.
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.
It's just cutting edge tech.
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?
> 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.
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
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...
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).
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.
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.
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.
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.
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.
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.
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.
I wonder if there was (or still is) a way to do something similar for Swift and SwiftUI.
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).
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.
I’d say give it a twist! If you like React you’ll like it, just has different trade offs.
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.
<Container>
<Text weight="bold">madeofpalk</Text>
<Image src={profilePic} />
</Container>
// 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 <Container>
{ isVerified ? <Tick /> : null }
<Text weight="bold">madeofpalk</Text>
<Image src={profilePic} />
</Container>
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.e.g.:
<Foo var={'a'}>
<Bar />
</Foo>
Becomes something like: React.createElement(Foo, { var: 'a' }, React.createElement(Bar))
It all boils down to React.createElement(component, props, ...children)
https://reactjs.org/docs/react-without-jsx.htmlSwiftUI is a definite move away from interface builder.
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?
However the fact that it's so easy to build new UI components, at this phase partly makes up for it.
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.
On what basis do you make that rather bold statement?
But now it seems like a lot of problems have been solved
https://stackoverflow.com/questions/59279176/navigationlink-...
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.
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 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 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.
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.
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.
What are the reasons for you to have this opinion?
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.
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?
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.
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!
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.
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.
Swift UI creates a mess of special cases pretending to be declarative, and does a poor job of it.
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.
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.
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 :)
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.
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.“‘X considered harmful’ considered harmful”, I guess.
https://meyerweb.com/eric/comment/chech.html
Now I await “Comments linking to the ‘considered harmful essays considered harmful’ essay on ‘x considered harmful’ discussions considered harmful”.
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.
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.
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...
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.
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.
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.
https://github.com/elm/json/blob/063aaf05e0dc5a642bacbdaae59...
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.
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.