iOS: add Appwin to your app
Learn how to add Appwin to your iOS app with the Swift package.
Before you start
- An app created in the dashboard
- Your App ID
- Xcode 16 or later, targeting iOS 16+
iOS has no install command: in Xcode, File → Add Package Dependencies,
paste https://github.com/appwin-dev/appwin-ios, then pick Up to Next Major
Version. The package has zero external dependencies.
Build your integration
Pick the products you want. The dependency list and the initialisation code follow your choice.
Build your integration
AppwinCore is always in - it carries the identity, the session and the network client. Pick what you add on top.
Use a prompt
Dependencies
.package(url: "https://github.com/appwin-dev/appwin-ios", from: "0.4.0")
.target(name: "MyApp", dependencies: [
.product(name: "AppwinCore", package: "Appwin"),
.product(name: "AppwinCommunity", package: "Appwin"),
])
Initialisation
import AppwinCore
import AppwinCommunity
import SwiftUI
@main
struct MyApp: App {
init() {
let appId = Bundle.main.object(forInfoDictionaryKey: "APPWIN_APP_ID") as? String
AppwinCore.configure(projectAppId: appId ?? "")
}
var body: some Scene {
WindowGroup { RootView() }
}
}
struct RootView: View {
var body: some View {
MyTabs()
.task {
try? await AppwinCore.bootstrapSession()
let community = await AppwinCommunity.initialize()
}
}
}
- Each initialize() answers rather than throwing. Gate your own entry point on the result - the SDK does not own your navigation, so it cannot hide your tab for you.
Put the App ID in Info.plist under APPWIN_APP_ID, fed by a build setting,
rather than pasting it into your source: the value differs between your debug
project and the one you ship, and a literal in init is the kind of thing that
reaches the App Store pointing at the wrong app.
<key>APPWIN_APP_ID</key>
<string>$(APPWIN_APP_ID)</string>
Put it on screen
initialize() says whether a product may open. Where it goes is yours - the
SDK does not own your navigation.
| Product | What you place |
|---|---|
AppwinCommunity | AppwinCommunity.communityView(), a view to embed |
AppwinSupport | AppwinSupport.presentMessenger(), or its MessengerView |
AppwinNotifications | No UI - registerPushToken(...) at launch |
AppwinAnalytics | No UI - trackEvent(...) |
if community == .ready {
AppwinCommunity.communityView()
.tabItem { Label("Community", systemImage: "bubble.left.and.bubble.right") }
}
A refused product logs loudly in a debug build, quietly in release, and falls back to a neutral view if you present it anyway. It never crashes, and it never silently does nothing.
Attach your user
Optional, and it is what makes a person the same in Community and in Support,
and across their devices. The externalId is yours - the one from your
database.
AppwinCore.identify(externalId: user.id)
try await AppwinCore.bootstrapSession(externalId: user.id)
await AppwinCore.signOut() // on sign-out
identify alone is not enough: replaying the bootstrap is what mints a token
carrying the new identity. Without it, the calls that follow stay on the
anonymous session until the next launch.