Mobile SDK - overview
The principle
The whole UI is native and lives in the SDK. Your app provides an entry point - a tab, a button - and the SDK draws the rest: the feed, the comments, the profiles, the messenger.
This is the Intercom model. It has one direct, deliberate consequence: you do not compose the screens. In exchange, you do not have to maintain them, retranslate them, or resubmit your app when a feature changes.
Customisation goes through the dashboard, not through code: colours, font, corner radii, active features, maximum lengths, moderation. The SDK re-reads its configuration on every open, so a change on the studio side applies with no redeployment.
Architecture
┌──────────────────────────────────────────────────────┐
│ Your app (Swift / Kotlin / React Native / Flutter) │
└───────────────┬──────────────────────────────────────┘
│ configure(appId:) once
▼
┌──────────────────────────────────────────────┐
│ AppwinCore (Swift + Kotlin) │
│ Device identity · session · networking │
└───────────────┬──────────────────────────────┘
│ shared
┌───────┴────────┬────────────────┐
▼ ▼ ▼
AppwinCommunity AppwinSupport AppwinNotifications
AppwinCore carries what is common: the persisted device identifier, the
authenticated session, the HTTP client, realtime. It is the reason one
configure is enough, and the reason an identified end-user is identified in
every product at once.
It exists in two implementations, Swift and Kotlin, with the same contract: same method names, same headers, same guarantees. A team that has integrated one platform does not have to relearn the other.
One difference worth knowing: the iOS keychain survives an uninstall, so the device identifier does too. Nothing offers that guarantee on Android - the SDK uses encrypted preferences there, included in the automatic backup, so the identifier comes back after a reinstall if the backup is on. Otherwise the user starts again with a new anonymous profile.
The product modules depend on it and know nothing of each other. You install only the ones you need.
What the SDK does
- Recognises the device with no sign-up, stably over time
- Opens and renews the authenticated session, with no token for you to handle
- Renders the native UI, themed from your dashboard
- Caches what it takes for the first screen not to flicker
- Applies the kill switches: a feature turned off on the studio side disappears from the interface
What the SDK does not do
- No composable UI. You cannot rearrange a screen or inject a component. If a screen does not suit you, that is a product conversation, not a setting.
- No storage of personal data beyond what is needed. The SDK does not read your address book and sets no advertising tracker.
- No React Native rendering. The
@appwin/react-nativepackage is a bridge to the native SDKs, not a rewrite: the feed and the messenger stay SwiftUI and Compose. A third rendering of the same screens would diverge from the other two at the first product change.
Minimum versions
| Version | |
|---|---|
| iOS | 16.0 |
| Swift | 6.0 (the SDK is built in strict concurrency mode) |
| Android | 7.0, API 24 |
| Kotlin | 2.1, JDK 17 to build |
| React Native | 0.73+ |
| Flutter | 3.3+ |
| Dart SDK | 3.9.2+ |
On iOS the modules are distributed through Swift Package Manager, Apple's
manager built into Xcode. No CocoaPods: no Podfile to keep up to date and no
separate install step. A deployment target below iOS 16 does not compile - the
SDK uses SwiftUI and async/await.
On Android the modules are Maven AARs (io.appwin:appwin-core,
appwin-support, appwin-community, appwin-notifications), built on Compose
and Material 3.
React Native and Flutter go through bridge packages - @appwin/react-native on
one side, appwin_core plus appwin_support / appwin_community on the
other - which expose the native screens without rewriting them. Both mobile
platforms are covered either way.
Next
- Installation
- Identity
- Community - the first product to wire