iOS SDK
A Swift package for regular iOS apps: a native support chat for SwiftUI and UIKit. Users write in their language; your team answers in theirs.
Making a game in Unity? Use the Unity SDK, which already covers iOS builds. This package is for apps written in Swift.
Install
In Xcode, File → Add Package Dependencies, then add this URL, from version 0.2.2:
https://github.com/inngame/sdk-ios
Requires iOS 16 or later. The package is called Inngame. The device token is kept in the Keychain.
Configure
Configure once at launch with your public app key (dashboard → your app → Install):
import SwiftUI
import Inngame
@main
struct MyApp: App {
init() {
Inngame.configure(appKey: "app_XXXXXXXX")
}
var body: some Scene {
WindowGroup { ContentView() }
}
}
configure(appKey:baseURL:) takes an optional baseURL if you run your own Inngame server.
Identify the user
Users start anonymous, so the chat works before login. After login, identify them. Pass a token, a JWT signed by your server with the app's identity secret, to mark them verified: only verified users get their history on every device. See Player identity.
// Unverified
Inngame.identify(userId: user.id, name: user.displayName, email: user.email)
// Verified, with attributes your team sees in the profile
let jwt = try await api.inngameToken()
Inngame.identify(userId: user.id,
name: user.displayName,
email: user.email,
token: jwt,
metadata: ["plan": "pro", "signupYear": 2024])
Show the chat
SwiftUI:
struct SettingsView: View {
@State private var showHelp = false
var body: some View {
List {
Button("Help & support") { showHelp = true }
}
.sheet(isPresented: $showHelp) {
InngameChatView()
}
}
}
UIKit (presents the chat as a page sheet):
@objc func helpTapped() {
Inngame.present(from: self)
}
The chat takes its look from the dashboard (Settings → Apps → your app → Appearance), with no app update: your logo in the title bar next to the title, and the accent, background, text, header, team bubble and player bubble colors for light and dark mode (or a preset: Inngame, Dark fantasy, Cartoon, Sci-fi, Minimal). Colors you leave empty keep the system look.
Messages written without network are kept on the device, shown as “Sending…”, and sent again when the network comes back or at the next launch (once, thanks to a client id). A message the server refuses for good (a blocked user, for example) leaves the queue instead of being retried forever.
Unread badge
Inngame.shared is an ObservableObject; unreadCount is published:
struct SupportRow: View {
@ObservedObject var support = Inngame.shared
@Binding var showHelp: Bool
var body: some View {
Button("Help & support") { showHelp = true }
.badge(support.unreadCount) // shown in List rows and tab items
}
}
In UIKit, subscribe with Combine: Inngame.shared.$unreadCount.sink { … }.
Context and events
Device, OS, app version and locale are attached automatically. Add your own keys; they're attached to the user's next messages and visible to your team only:
Inngame.setContext("screen", "Checkout")
Inngame.setContext("orderId", order.id)
Inngame.setContext("orderId", nil) // remove
Send events for automations, which can answer with a message or open the chat:
Inngame.track("checkout_failed", properties: ["step": "payment"])
Push notifications
Pass the APNs device token so replies reach the user when the chat isn't open. Upload your APNs key in the dashboard (see Integrations).
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
#if DEBUG
Inngame.setPushToken(deviceToken, sandbox: true)
#else
Inngame.setPushToken(deviceToken)
#endif
}
When a notification is tapped, let Inngame recognize it. It returns true for Inngame notifications and sets Inngame.shared.wantsToOpen, which you can observe to show the chat:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse) async {
if Inngame.handleNotification(response.notification.request.content.userInfo) {
// Open the chat (or observe Inngame.shared.wantsToOpen in SwiftUI)
}
}
Logout and data deletion
// The user signed out: this device starts over as a new anonymous user
Inngame.logout()
// Right to erasure: deletes the user, their conversations and photos
try await Inngame.shared.deleteMyData()
API reference
| Call | What it does |
|---|---|
Inngame.configure(appKey:baseURL:) | Starts the SDK. |
Inngame.identify(userId:name:email:token:metadata:) | Links the device to your account; verified with a JWT. |
Inngame.logout() | New anonymous user on this device. |
Inngame.setContext(_:_:) | Custom context on the next messages (nil removes). |
Inngame.track(_:properties:) | Event for automations. |
Inngame.setPushToken(_:sandbox:) | Registers the APNs token. |
Inngame.handleNotification(_:) | true if the notification is from Inngame; sets wantsToOpen. |
InngameChatView() | SwiftUI chat view. |
Inngame.present(from:) | Presents the chat from a UIKit view controller. |
Inngame.shared.unreadCount | Published unread count. |
Inngame.shared.pending | Published messages not yet accepted by the server (offline queue). |
Inngame.isUnavailable | true while your support is unavailable (your Inngame workspace is suspended); also published as Inngame.shared.isUnavailable. The chat then says “Support is unavailable right now. Please try again later.” in the user's language and hides the composer; unsent messages wait in pending and are sent once support is back. The SDK checks again every 10 minutes while the chat is open and each time it opens, and returns to normal on its own. Meanwhile deleteMyData() throws an InngameError with isSuspension. |
Inngame.shared.deleteMyData() | Erases the user's data (async throws). |