Use Kotlin Multiplatform With a Network Listener Project

Kotlin Multiplatform (KMP) simplifies implementing shared features in cross-platform projects, allowing you to set up platform-specific dependencies without having to completely overhaul your codebase. Its flexibility and versatility make KMP an exceptional and thoughtfully designed development framework.
In the first article in this series, you put all the foundational elements in place to start using Kotlin Multiplatform. Now you’re ready to implement platform-specific dependencies from their respective modules. A practical example to illustrate this is creating a simple network listener.
To help guide you, I have created a video to showcase the result of your work.
Start Using Kotlin Multiplatform
If you’ve developed apps before, you’ve probably encountered scenarios where you needed to inform users about their internet connectivity, be it an offline status or a disabled connection. Android developers typically employ the ConnectivityManager
, while iOS developers might use NWPathMonitor
.
Accessing ConnectivityManager
in the Android module is straightforward with the androidContext()
function provided by the Koin dependency injection (DI) framework for KMP. However, in December 2023, I observed that NWPathMonitor
isn’t included in the prebuilt libraries for Kotlin Native, so I used an interface to integrate it using Swift code. This approach involves leveraging the IosApplicationComponent
to bridge the NWPathMonitor
class from the iosApp
module to the composeApp
module shared by Android and iOS.
First I’ll conceptualize the interface. At its core, the network listener must perform two fundamental actions: initiating the listening process and ceasing it when necessary. To do so, define two functions: registerListener
to start the listening and unregisterListener
to stop it; then encapsulate these functionalities within an interface named NetworkHelper
. This interface is also designed to notify you about network status changes, providing callbacks to indicate when a network connection is established or lost.
Implementing this interface on Android is pretty straightforward. Go to the exact location in your androidMain
module and create a new class called AndroidNetworkHelper,
which implements the NetworkHelper
interface. This is a pretty standard implementation.
You still want to make this class available in the dependency injection (DI) graph described in the previous article.
Now for the fun part: In the iosApp
module, go into the iosApp
folder and create a new Swift class file called IosNetworkHelper
. You should do this using JetBrains Fleet or Apple’s XCode code editor:
Notice that the Unit
return type is now represented as a Void
type. That’s due to the Kotlin Native Obj-C interoperability mappings.
Now that you have an iOS implementation leveraging the Network
package native to the iOS ecosystem, you can integrate it into the IosApplicationComponent
. To do this effectively, first define it within the component:
Lastly, to piece the puzzle together, make it available to Koin:
Complete the Implementations
You now have everything you need to complete your NetworkListener
implementation. Return to the commonMain
source set and create a class called NetworkListener
:
This class utilizes Kotlin’s flows to tap into the capabilities of the NetworkHelper
methods you established previously. This NetworkListener
class can be seamlessly injected into the DI graph within the commonMain
source set, further streamlining its integration and use.
To wrap it all up, go to the App.kt
composable and test the network connectivity:
Conclusion
This two-part article provided a step-by-step guide to calling platform-specific dependencies in Kotlin Multiplatform. While I’ve applied some creative approaches, the majority of the patterns discussed are derived from various sources, including blogs, official Kotlin and JetBrains articles, documentation and KMP samples, including:
- The Basics of Kotlin Multiplatform Project Structure
- Kotlin Multiplatform Samples
- Using Platform-Specific APIs
- Expected and Actual Declarations
- Interoperability with Swift/Objective-C
The shift toward remote and borderless hiring enables companies to look beyond geographical constraints to access global talent. Explore strategies to build high-performing, globally distributed teams by downloading The Future of Hiring Is Borderless.