What's incredibly annoying is that a lot of the SwiftUI components are just wrappers around the equivalent UIKit components (eg. ScrollView/UIScrollView), but are missing a lot of the functionality of the underlying components.
These should really be open source: it's such a waste of time to have to experimentally poke around to see how the SwiftUI components interact with their UIKit counterparts, when these should really just be straightforward wrappers.
In many cases, the declarative APIs are just poorly thought out and/or clearly not "battle tested", and there is a lot of API churn in really crucial components which are also often not backported to older OS versions.
It's funny, when SwiftUI and Compose were coming out we waited a bit but jumped in as soon as we could. With Compose, our early versions required us to make builds of Android Studio on our own machines that supported it. But even then Compose felt more polished in a lot of ways - and if we ran into issues we could _see the code_ and make our own components with the changes we needed if necessary.
SwiftUI is great, really, but has so many rough edges, gotchas, and bugs. They do get fixed, but you're still supporting 4 year old versions of iOS without those fixes, so you're screwed.
Just completely boneheaded not to open source SwiftUI from the start, especially with how great the open source Swift community is.
Since it’s trivially easy to bridge a UI/NSView into SwiftUI, why don’t you do that? If you think of SwiftUI as a dumbed-down children’s toy box version of the grown-up’s tools, there’s nothing to complain about. It’s really better that way since UI/NSKit has so many footguns.
I don't see SwiftUI as a "dumbed-down children's toy box" at all -- SwiftUI is excellent conceptually. I am just frustrated that the "SwiftUI standard library" that Apple ships with it is so rudimentary, as if we didn't already have over a decade of prior art of how to implement declarative APIs for basic components.
The worst offenders by far are the scroll & list views, which are basically useless. As a starting point, there is no way to get the current scroll position from a scroll view in iOS <18.
So yes, I often have to wrap the UIKit components myself, and deal with all the joys of UIKit I was hoping to finally avoid...
Apple did exactly the right thing with Swift itself: the Swift forums are excellent, and it's clear that Apple employees use these to prioritize the (very real) Swift bugs and limitations. Why does this not exist for SwiftUI?
I agree with you, but I actually like UI/AppKit so I’m biased. The only “pure” SwiftUI components I trust are Button, Image, and Text. Everything else gets built out “old-school” and wrapped in a UIViewRep. It’s just so much easier that way.
SwiftUI Lists are half baked. Sheets and popovers feel like they were implemented by a stoned intern that thought it would be funny to troll everyone.
This is only true for the very simple cases you might see in an example snippet. If you need a UIView because you need access to some kind of imperative action (which is usually why you need a UIView), there is no channel for that. Declarative vs imperative are fundamentally incompatible when in the same abstraction layer. You have to use the kind of hacks you used to only see in "bad" codebases, like notification broadcast instead of delegated function calling.
Not sure I follow. Have you seen UIViewRepresentable? You can turn a UIView into a SwiftUI view in 5 lines of code. If you need to move state there is a two way bridge you can choose to implement called a Coordinator. It is a blank protocol with zero obligations to fulfill and only exists as convenient a reference type simultaneously accessible by both the UIView and the SwiftUI parent.
I can’t imagine how it could be implemented more simply.
Even if you are rendering a complex chain of compute shaders with multistage heap fences onto a process shared IOSurfaceRef with several concurrent threads greedily realiasing your scratch buffer to queue up more work, it doesn’t matter. Eventually you’ll up with a UIView or CALayer and it’s still just one function call to bring it into SwiftUI.
That would be an extremely good thing to explain in the introduction. I feel like this kind of very culturally-specific usage of everyday words is what makes math/CS papers so impenetrable for many people.
The word "easy" is another example: saying "it is easy to show X" (just?) means that X can be derived from the already stated theorems in a more-or-less mechanical way without having to introduce new concepts. It does not in any way suggest that deriving this will be "easy" for a student reading the paper.
(Of course the most challenging "easy" parts are best left as an exercise for the reader anyway...)
I always recommend fish to anyone who doesn't (yet!) have strong opinions about their shell.
Immediately seeing if you misspelled a command because the color changes is a huge benefit if you're not super familiar with the command line.
The auto-complete and suggestions are also miles better than bash - they are automatically generated from man pages, so most commands have a usable set of completions.
The web-based config lets you easily tweak settings that would otherwise be an incomprehensible soup of PS1=3!@*(!@!@ gobbledygook.
Also, it mostly "just works" out of the box, so you really don't have to waste any time setting anything up if you don't really care.
> The auto-complete and suggestions are also miles better than bash - they are automatically generated from man pages, so most commands have a usable set of completions.
I never understood this. It's always seemed worse - in bash/zsh I can tab complete branches/tags etc in git, pods/deployments etc in kubectl. I try that in fish and it'll just list files in my PWD
As many others have mentioned, dotfiles in a git repo (https://github.com/lachenmayer/dotfiles), mainly for having unified shell themes/aliases/etc. on all machines I use.
This is by far the most infuriating thing about the PR UI, along with the fact that you can't comment anywhere outside of the "patch", meaning you can't point out anything that is more than a couple of lines away.
Flutter suffers on iOS because it completely takes over the render surface (ie. it renders everything using Skia), and doesn't offer any escape hatches for native components. In a way, this is an amazing approach: it completely sidesteps a lot of the platform-specific woes that plague React Native, and makes it much easier to support completely new platforms (ie. if you can get Skia to run on it, it can probably run Flutter).
But particularly on iOS, the native components have some incredibly subtle behavior (eg. the "fling" gestures from UIPageViewController, the native modal animations, overscroll, etc.), and these are extremely difficult to get right.
React Native's story for native inter-op has recently become miles better with JSI, which allows native<->JS FFI at much better performance than the previous approach. This has enabled libraries like Reanimated 2 (https://www.reanimated2.com/) and Gesture Handler 2, which take full advantage of this and get React Native apps tantalizingly close to "truly native"-feeling.
My former firm put a lot of effort into Flutter as a preferred alternative to RN or native app dev -- including standing up a lot of onshore/nearshore/offshore experience -- but we never were able to to make it a viable alternative on anything other than small or trivial apps, due generally to performance problems, weird iOS corner cases, hard-to-debug crashes arising from deep within the framework, and sharp edges on their emulated components. From a governance perspective, we ran into difficulty rapidly spinning up new dev capacity relative to RN (where you can have a web developer productive within a few days, as long as they've got a mobile dev running their pod to oversee integration and build). I'd love to see Flutter become a strong alternative, but I'm not sure Google is willing to drop enough of its NIH syndrome to meet developers where they are, rather than where they want devs to be; until then, it's a tech to push further out on the radar until it's more battle-tested, especially on iOS.
While Flutter and RN might be improving in many ways, it feels like the risk/reward tradeoff is actually getting worse for using a unified app layer. The underlying platforms getting easier to use themselves (Kotlin, Swift, SwiftUI, Jetback, etc) and the developer market getting stronger skill-wise at developer apps. There is more of a consolidation of best practices etc. The reward for building a single codebase becomes very low, but the risk is remaining high. You are adding a layer of indirection and dependency right in the middle of the platform. You basically cannot evolve at the speed of the platform. Sometimes platforms move fast and you want to capitalize on change. This always made it seem like non-starter for me.
there are developers who are just happy to write the same logic in multiple languages, and there are those who find it extremely mind-boggling, this is regardless of how nice/easy to learn those languages are.
Nobody is happy to write the same logic in multiple languages. There are other ways to package logic and have it be consumable by multiple teams building native mobile apps for various platforms. If you are trying to solve this by very specific problem by adopting something like React Native or Flutter then I would question many other things beyond this.
> There are other ways to package logic and have it be consumable by multiple team
Really what way? Make a backend endpoint? Convert to C++ and invoke as native code? I'm only speaking for react native it's more than sharing code it's sharing skill, a web/nodejs dev can learn it and jump on company's mobile app when needed, as opposed to have dedicated devs for Android and iOS who sit around doing nothing sometimes and stop company from shipping when they go on vacation.
A few years ago I would have agreed that the native subtleties must be a top priority for user experience, but these days I don't think it matters that much anymore.
Flutter's UI can't match native components exactly, but they do a very good job, and I don't think the vast majority of users would be able to notice the difference or cares that much.
The reality is, the native UI homogeneity is long dead anyway. Every app, website, brings it's own set of UI components and styling. It's all inconsistent and people are used to it.
It really does not matter whether your modal dialog is native or not, as long as it follows basic abstract UX conventions of looks and behavior.
Native UI parity went extinct because platforms kept changing UI guidelines in every major release to keep things feeling "fresh" and new. A native app might inherit a lot from the toolkit but it'll still look weird without an update.
At some point, you're better just doing your own thing rather than be dragged around on the leash of some product manager looking to make a splash at the next conference.
I develop with React Native in my day job and I'm observing all the UI changes that are happening in the systems. So far there aren't many problems with the differences, for example in the alpha version of Android 12, Google introduced a sparkly ripple effect (they eventually removed it again). But this change was automatically propagated to all our interactive components of our React Native app, no changes to our codebase necessary. And this is the case for many other changes, since React Native uses actual native elements.
> I don't think the vast majority of users would be able to notice the difference or cares that much.
Users do notice these things. They just can't explain it in technical terms like "i feel like this app is built with a non-native toolkit that is why animations are wrong".
They explain it as "this feels off" and "why doesn't it run like X" and "I don't like it" etc.
I think long-time users of Apple's various platforms will notice, especially. I bought my first Performa back in 1996. That old OS -- especially up against Windows 95/2000/XP apps -- conditioned people to be UI snobs. If I download an app from the App Store, and something rubs me the wrong way within the first few seconds, I will almost always ditch it. I want a native experience, and I don't think I'm alone.
It boggles my mind that anyone invests precious time and effort chasing such a fickle group of users. Anything less than Apple's vision of perfection and harmony or you'll be dumped in a heartbeat. "Think Different" indeed.
The people willing to put up with mediocre and bad software aren't willing to spend money on it either. Just look at the revenue gap between iOS and Android. It makes sense that people put time and effort into pursuing the fickle users willing to pay money.
If you've been around that long, you know that Apple changes their UI guidelines sometimes and not always for the better. I no longer know what a "native experience" is supposed to be. (I haven't even used Monterey yet.)
And then Kai's Power Tools came along with its completely unique UI and everyone loved it. And other developers decided to emulate that idea - that a funky UI is a differentiator.
I don't think it's fair to blanket blame Flutter though. What you are noticing are poorly made apps. What you are not noticing are well made Flutter apps, that are almost indistinguishable from native apps. I guarantee you we all interact with way more different UI frameworks then we are aware of on a daily basis.
Some apps also fail by trying to emulating native UI so hard, when it would be better advised to just adopt a more abstract style. Today's flat UI is just simple shapes after all.
From technical a standpoint, Flutter definitely is performant, capable of delivering smooth scrolling and 60 fps. Your experience may vary of course, but I've been shipping an app with it for 2 years now and things been working out well. Can only really say great things about it.
> What you are not noticing are well made Flutter apps, that are almost indistinguishable from native apps. I guarantee you we all interact with way more different UI frameworks then we are aware of on a daily basis.
That is, indeed true. So the question becomes: does the framework nudge you towards and help you with making well-made apps almost indistinguishable from native apps, or the opposite :)
I'd wager these sentiments have more to do with performance/responsiveness than they do with whether or not UI elements and animations are system defaults. Pretty much every wildly popular application in the market has a totally custom UI.
I kind of disagree. I don't mind apps that bring their own visual styling and don't reuse OS components/styling, but I get _really_ annoyed by apps where gestures behave slightly differently. Things such as the exact tolerances required to activate the "fling" getsure, or to swipe from the edge, are really frustrating when they're not quite right. Beyond basic conventions, the minute details of how the user input/output responses work are really really important.
I hate it when swipe is inconsistent. Even using two Microsoft products (Todo and Outlook) on my iPhone, in Outlook you swipe right to delete a message from the list, in Todo you swipe left to delete a task from the list :-/ . Lucky "undo" is easy to find.
No. I'm a hardcore iOS user and i can recite off-hand specific apps that run "wrong" and why i hate using them (because if their UI). I tend to actively minimize using them when possible too. If your app doesn't support the "scroll to top" gesture when i tap the top bevel of my screen, i will stop using it if i can find alternatives.
Yes, i know that it runs wrong because its ReactNative and not SwiftUI, but you don't need to know why its wrong to know its wrong.
Eg:
Alexa App doesn't go back a frame when you swipe from left, you have to click back button.
In the React Native app I'm working on, I actually noticed this gesture on an iOS simulator (I didn't know about it before) and it worked well. React Native uses native components to render the UI, but it uses JS for the logic of what and where should it put the native components. I think this might be an issue in Flutter though.
> ...doesn't offer any escape hatches for native components...
Lest anyone read this the wrong way: you absolutely can embed native components in your Flutter app. They have a scheme called "platform views" that involves splitting the scene hierarchy above and below a native component, and this is used for stuff like web views or map controls that are firmly native components which people want to drop into their app.
> it completely sidesteps a lot of the platform-specific woes
This is the key point where Flutter wins over both React Native but also the native Android and iOS toolkits. When you design a screen in Flutter, it will behave as you expect on every different version of Android and iOS. You just check it does the right thing as screen size changes (which is usually pretty easy to implement, and very easy to test) and then you get predictable behaviour. It is so rare that you need to fix X screen on Y phone running X version of the OS because it has odd behaviour, and that happens all the time with any of the native toolkits.
That said - I haven't used Swift UI, so it's possible the situation has improved (although I wouldn't bet on it).
Last year I was looking at using Flutter for something that needed extensive use of a WebView, I very quickly came to the conclusion that they are having massive difficulty to get it working well due to the Flutter architecture. It looks like the situation has improved but just look at the web_view issues, there are a lot of them:
That does look good if you have control and its somewhat simple html.
The particular use case I was looking at was integrating a web based rich text editor based on contenteditable. It had to be a proper webview, and the issue is that the interaction with the text (cursors/selection/typing/onscreen keyboard) was completely broken.
I was gonna say, “look, Flutter looks like peering at a screen through a fishbowl, responds like your hands are in some kind of jelly glove, and feels like you’re two martinis into happy hour,” but technical responses are of course better appreciated with this crowd.
Love this idea. I could imagine this being a great way to alert people to product recalls, or even start class action lawsuits in extremely serious cases.
Picnic is a new group chat app, built for close friends (https://picnic.chat).
Group chats matter, and they matter more than you might think. For billions of people, they've come to play a vital role in our most important relationships: the space online where our real friendships live. We believe the one-size-fits-all, functional apps where our group chats live today could be so much more. That's why we are on a mission to build a better home for people's favourite group chats: one that is more joyful, more intentional and more ethical.
It's an exceptionally good time to be joining our small but mighty founding team of top engineers from Facebook, Apple, Google and more. We are fresh from raising a £2.1m Seed round led by top tier VCs (announcement coming soon) and are backed by the likes of Robin Dunbar (the man behind Dunbar's number), Snapchat's 1st Engineer and many more world class operators.
We're looking to hire somebody who is comfortable working as a key part of a small team, with experience of having shipped consumer-facing mobile apps. The Senior in our job title does not refer to how many years of experience you have (or your degree!), but to your general approach to development: you are able to think about the system and architecture as a whole, know enough about all aspects of the stack to effectively diagnose issues, and are able to pass your knowledge onto other members of the team.
[0]: https://effect.website/