That's the problem now though. We've made it so apps have to be approved by gatekeepers, and are highly discouraged by the gatekeepers from sharing state with other apps on the same device.
Then the recommendation if that's a problem for you is to use the web. But sometimes the web doesn't work, as is the case here, because it requires the user to trust third party code in real time and give sensitive data to third party servers they don't control.
So we have everything pushing the user to put their most sensitive information into some third party service that should be an app, but isn't, because cloud.
I'm not talking about sharing state with your webserver, I'm talking about two apps on your phone sharing state directly with each other without ever leaving the device or becoming accessible to a third party.
Desktop operating systems have a slew of ways to facilitate this, and the mobile gatekeepers keep eroding them. They're also terrible at dependency management (a completely solved problem in real package managers), which discourages creating apps that depend on other apps.
There are still ways to do any given thing, but if you make it harder then you make it rarer.
> My understanding is the app permission model never asks for network access, so all "apps" are effectively web clients with a fancy UI.
At least for Android, not exactly: they still have to require network access (android.permission.INTERNET), and you can check if they have done that in the Play Store (description → Read More → App permissions). What changed is that the Store won't explicitly ask you to confirm you're OK with it when installing.
In any case, typical native applications didn't have to ask for network access either, that didn't make them all effectively web clients. Many of the mobile apps I have installed don't rely on a central service.