This is cool, but it's worth noting that depending on how network-heavy the app in question is it may not be advisable to build the networking portion of an app as part of the shared core.
The reason for this is because iOS has a multitude of device specific optimizations built into the native networking stack to my knowledge is opted out of with the usage of cross platform networking. This includes features coalescence of calls across apps to occur when the antenna is already awake (to save power) and transparent management of multi-connection situations (e.g. when the phone has both wifi and cell available). The result is more power used and less fluidity in some situations.
I don't think this is as much of an issue on Android where third party networking libs like OkHTTP are the norm anyway.
With this in mind I believe the best functionality to put in a shared core is generic common logic which does not have platform optimizations.
A handy feature of NSURLSession comes to mind: You can configure requests to enqueue „forever“ (eg when offline) until they are finally successful. No retry mechanism necessary, or exponential backoff which can add nontrivial idle time.
Features like this one are certainly not available when using an alternative networking stack.
There is for instance a KMP module which relies on OkHTTP on Android and wraps NSURLSession on iOS - while exposing a common interface in Kotlin. The name escapes me at the moment. No reason you can't do that with Rust, but there's no reason to do that either, in my opinion. I agree that this probably isn't the right boundary at which to do your code sharing.
On the other hand your shared code can parse or generate data and pass it to/obtain it from a platform specific networking layer.
This problem hasn’t been solved yet, but I think it is solvable. I’ve been writing a lot of cross-platform Rust and think these would help a lot:
- Add an NSURLSession backend to reqwest. The abstractions match well, and Obective-C interop is pretty solid
- A Tokio API compatible networking implementation using the Network framework’s C API. Not quite sure how well this would work, but I think it’s possible.
I will try to build these at some point
ktor.io successfully does the first thing for Kotlin Multiplatform, multiplexing all of OkHttp, NSURLSession, fetch and others
Given that the README literally has Android support and build instructions, it would be helpful if you qualified your comment with more than a one-liner like that.
Can you detail, say, why curl as a backend isn't necessarily sufficient here?
I spent some time doing exactly this a couple of months ago, and I agree, Mozilla's UniFFI is really cool. It's also what I'd probably recommend at this time if you're trying do Rust code sharing across higher-level platforms like iOS and Android.
You do have to write an export header spec in 'UDL' (a Mozilla authored interface definition language with a JetBrains plug-in to make it easier to write) - but in exchange, you get proper (idiomatic) Kotlin, Swift, Ruby and Python bindings for your Rust modules. It's nice that for instance the Swift bindings are actually 'native' instead of implemented via Objective-C interop (which would have arguably been simpler).
[edit] I should note that the Kotlin bindings are a little wonky for non-scalar types because they're exported as AutoCloseable resources, and care must be taken to use them correctly. [1]
UniFFI is pretty amazing productivity-wise for sharing common components across clients and teams. I haven’t really figured out the WASM side yet though or if it’s even really feasible.
The reason for this is because iOS has a multitude of device specific optimizations built into the native networking stack to my knowledge is opted out of with the usage of cross platform networking. This includes features coalescence of calls across apps to occur when the antenna is already awake (to save power) and transparent management of multi-connection situations (e.g. when the phone has both wifi and cell available). The result is more power used and less fluidity in some situations.
I don't think this is as much of an issue on Android where third party networking libs like OkHTTP are the norm anyway.
With this in mind I believe the best functionality to put in a shared core is generic common logic which does not have platform optimizations.