iOS: add Appwin to your app

Learn how to add Appwin to your iOS app with the Swift package.

Before you start

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.

AppwinCore

Use a prompt

Dependencies

swift
.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

swift
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.

xml
<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.

ProductWhat you place
AppwinCommunityAppwinCommunity.communityView(), a view to embed
AppwinSupportAppwinSupport.presentMessenger(), or its MessengerView
AppwinNotificationsNo UI - registerPushToken(...) at launch
AppwinAnalyticsNo UI - trackEvent(...)
swift
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.

swift
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.

Where to go next