Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> The most important question for every cross platform framework is what happens to the UI?

I kindly disagree. The first feature I want from a cross-platform framework is that it lets me write a native UI. That's why I like KMP: I can just share a framework with an iOS app built with SwiftUI.

Sharing business logic makes a lot of sense in a ton of cases and has been done forever (C/C++/Rust/Go libraries, etc). Sharing UI in complex apps, in my experience, always ends up being a "write once - debug everywhere" nightmare.

What KMP (and I'm hoping Swift for Android) bring is the possibility to share a Kotlin (respectively Swift) library instead of sharing code with C/C++/Rust/Go. So that an Android/iOS team can keep using Android/Swift without having to introduce a third language for sharing logic.



Indeed, "cross-platform UI" can only be as good as the average between all the platforms it supports and it usually ends up costing a lot more than using the native UI kits of each platform. Kotlin Multiplatform has been and continues to be the "happy path" for buildings apps in our studio - native UI + shared business layer. Also, in terms of API stability and mental load, Kotlin is a lot more productive than Swift... and it doesn't come with a yearly breaking cycle.


« kotlin is a lot more productive than swift »

care to elaborate ?


Having worked a long time with client teams as a lead - this is always the biggest pain in the ass.

At one of my last phase startups I started shifting all our business logic stuff into our graphql server and treated it like it was part of the client teams. (we had ios/android/web as independent full apps with a very small team of devs).

Business logic is the real killer. Have one person suck it up and do it in typescript (sorry y'all) on the GQL/apollo server and all the clients can ingest it easy.

Send down viewmodels to the clients not data models. etc etc.

This helped DRAMATICALLY with complexity in the clients.


So your takeaway is that business logic should be done on the server. Hasn't it always been like this?


Has been the true core vision of the web if not mobile. If I remember correctly, that is how the original Basecamp was implemented, or Craigslist (still is?)... or this very website


Also I just realized the irony of them using GraphQL. They've really come full circle


OP is likely talking about local business logic, ie password field is min 3 chars long. You validate that in the FE before sending it up to get instant feedback to the user.


Your API should be fast enough and hosted on the edge so that the server side validation is instant feedback


There are external factors apart from your own API that can impact latency, for example a user could be in an area of poor internet connection or have a slow connection. Users do not live in our perfect development environment bubble where everything just works, it’s important not to assume that.


If it takes 1 second for a small percent of users to get form validation back it won't impact the business


That's how we got to "download 50 GB before playing a game on a console is fine", feels like we just stopped carying. Sending the form to the BE just to do same basic validation adds so much latency to the UI that it feel unusable for many/most users.

Related: A few Sundays ago I wanted to play Anno again. Sadly it was not installed on the Laptop I used. So i started downloding it because you won't get it on DVD/as iso-file today). Now it's a few Sundays after and I didn't play yet - because the download took 7 hours.


That's such a ridiculous logical falacy. You already have to send the form input to submit the form in the first place and you already need server side validation.

I just checked one of my app's register page (which makes > $2M ARR). If you submit a short password it returns an error from the backend that says "Password should be at least 6 characters.". (It uses Supabase). But yeah, that is so unusable it is basically the same as taking 7 hours to download a game onto your Playstation. Great logic!


What if you want your app to work offline?


And not just off-line, but as we learned last week, if us–east-1 is down you have spotty connectivity, not hard down, and your device needs to not cook your users; literally in the case of Sleep8.


We've really hit a strange level of dystopia when your bed doesn't work because a server is down


It was a near real-time messaging application. So not really applicable (other than seeing messages you already received - which could be cached from previous sessions).


I guess I'm not clear on what you mean about putting business logic in the client. It can't only be on the client side. If you do so, then obviously you have to replicate it on the server to check that the client was sending the right results, no? Not to mention avoiding thread races and double inserts and whatever else may have gone stale on the server before you allow a client to validate something? Even if your code isn't public-facing, the server still needs to check everything. As a solo dev it seems insane to me to ever put business logic in the client, unless the client and server literally share the same typescript codebase for crosschecking ops, and even then the server needs the same code plus additional safeguards. It baffles me that anyone would write a platform from the ground up with primary business logic on the client side, if the server isn't written in the same language. Maybe some simple initial validations and checks to avoid bombarding the server, but the server has to be the central source of truth.


That’s the exact opposite of what the GP is suggesting. Read this again:

> Business logic is the real killer. Have one person suck it up and do it in typescript (sorry y'all) on the GQL/apollo server and all the clients can ingest it easy.

Move the logic to the GQL retriever so that clients don’t have to implement business logic.


Yeah, I understood what they said. I'm wondering why the previous owners of the code decided to put business logic in the client.


we had a lot of very talented iOS devs that started running away with feature development when the server team couldn't keep up.

This really hurt the android + web client teams.

Eventually our backend started changing (mono-rail -> microservices) and it turned into an absolute cluster of trying to massage/cram new data models into the existing ones the iOS team created.

Late stage startup and then post finding product market fit problems.


OP is likely talking about local business logic, ie password field is min 3 chars long. You validate that in the FE before sending it up to get instant feedback to the user (yes you also have it on the server).


  > What KMP (and I'm hoping Swift for Android) bring is the possibility to share a Kotlin (respectively Swift) library instead of sharing code with C/C++/Rust/Go. So that an Android/iOS team can keep using Android/Swift without having to introduce a third language for sharing logic.
have gone down this route before, and tbh the biggest issue is dev ux (ios devs cant debug easily, model mismatches vs kotlin e.g kotlin exceptions cant be caught from swift) and in the end even kotlin multi platform isn't the same as kotlin for android, so in a sense you are still introducing a 3rd language after a fashion...

if you can fix the dev issues and have a dedicated team behind the shared logic it could work out, but still then again if you also have a website your re-implementing that logic on the front-end twice...


> e.g kotlin exceptions cant be caught from swift

FWIW the approach that swift-java takes in managing interop with Java (and potentially Kotlin) function calls means it is perfectly possible to to catch exceptions thrown by the JVM using wrappers that catch and rethrow them as Swift errors. So there would be a distinction here with bringing Swift calling into JVM-based code running on Android.


  > catch and rethrow them as Swift errors
yes, in fact we implemented some wrappers for that which was done using custom annotations from the kotlin side, though if you forgot to apply it, an exception would crash our ios app… which was unfortunately not the greatest experience for ios users (who were the majority of our customers anyways)


Sure. I guess my point was that maybe your devs are more comfortable doing it in Kotlin than in C/C++/Rust.

And IMO not everything should be shared; it's worth sharing complex logic because the overhead of sharing beats the overhead of writing it twice. But in many situations it is not slower to write it twice. And I am an advocate of writing the UI on each platform to have a truly native experience for the users.


> if you also have a website your re-implementing that logic on the front-end twice...

Which argues for react-native, warts and all.


Until Static Hermes gets here it seems like a big performance loss to move to React Native.


I’ve experienced much the same as you but that’s one of the reasons I’m interested to see where Swift on Android goes. These problems are solvable, it’s just that current implementations haven’t solved them satisfactorily.


> Sharing UI in complex apps, in my experience, always ends up being a "write once - debug everywhere" nightmare

Compared to the tried and true method of "write many times - debug everywhere".

there is not a world in which you won't have issues on $PLATFORM because $PLATFORM themselves have their own individual bugs / issues


> Sharing UI in complex apps, in my experience, always ends up being a "write once - debug everywhere" nightmare

Amen!


> > The most important question for every cross platform framework is what happens to the UI?

> I kindly disagree. The first feature I want from a cross-platform framework is that it lets me write a native UI.

I don’t understand – aren’t you agreeing?


Actually you're right, I am :-).


>> The most important question for every cross platform framework is what happens to the UI? >I kindly disagree.

You're still discussing the question of UI though, whether it's native or not.


React Native is pretty good at cross platform but yes, it must be tested right away on all platforms.

Retrofitting an iOS-only React Native app to Android later is possible but can be of a pain, at least initially.


My experience as an Android user is that React Native apps don't feel "Android native". Maybe it's because I only notice the apps that have the poorer UI, I don't know.


React Native apps can be made to feel native but it takes some knowledge and skill. In certain cases, a bit of native code might be required instead of off-the-shelf libs.

For example, I was looking for a way to perform certain computations on a stream of frames from the camera. Most libraries available I found would send the image frames to the JavaScript side first and do the computation there. Unfortunately, that was never 60fps because the amount of data being copied/serialized was too large. The solution was to write a bit of custom code that performs the computation on the native side and only ship the computed result (tiny JSON) to the JavaScript side. The end result was easily 60fps and felt 100% native.


> Sharing UI in complex apps, in my experience, always ends up being a "write once - debug everywhere" nightmare.

Was that with UI framework that wraps platform's UI framework or with one that draws controls on its own? Shared complex UI is not much of an issue with frameworks that fully implement their own controls. But quality implementation of controls from the ground up is a lot of work so there's not many good UI frameworks that do this.


This isn't disagreeing


Just realising now. Fortunately I was only "kindly" disagreeing! :-)




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

Search: