Embed the widget in mobile apps
Add the Quackback widget to native iOS and Android apps: install, configure, identify signed-in users with a server-signed ssoToken, open views, and listen to events.
The iOS and Android SDKs embed the Quackback widget in your native app, with a floating launcher, signed-in user identification, and event callbacks. This article covers installing, configuring, and identifying users on each platform.
The mobile SDKs wrap the web widget, so the tabs, settings, and identification rules are the same as on the web. See Widget overview.
iOS
Requirements
- iOS 15 or later
- Swift 5.9 or later
Install with Swift Package Manager
In Xcode, go to File > Add Package Dependencies and enter:
https://github.com/QuackbackIO/quackback-iosOr add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/QuackbackIO/quackback-ios", from: "1.0.0"),
],
targets: [
.target(name: "YourApp", dependencies: ["Quackback"]),
]Configure and identify
import Quackback
// 1. Configure once at app startup
Quackback.configure(QuackbackConfig(
appId: "your-app-id",
baseURL: URL(string: "https://feedback.yourapp.com")!,
locale: "fr" // optional; omit to auto-detect
))
// 2. Identify the signed-in user with a token signed by your server
Quackback.identify(ssoToken: fetchedSsoToken)
// Skip identify for anonymous visitors
// 3. Show the floating launcher
Quackback.showLauncher()The ssoToken is the same short-lived JWT the web widget uses. Have your backend sign it and send it to the app. See Identify users.
If you already know the user at startup, pass the identity to configure:
Quackback.configure(
QuackbackConfig(appId: "your-app-id", baseURL: URL(string: "https://feedback.yourapp.com")!),
identity: .ssoToken(fetchedSsoToken)
)
// Omit `identity` for anonymous sessions.Configuration options
QuackbackConfig(
appId: String, // required
baseURL: URL, // required
theme: QuackbackTheme = .system, // .light | .dark | .system
position: QuackbackPosition = .bottomRight, // .bottomRight | .bottomLeft
buttonColor: String? = nil, // hex, e.g. "#6366F1"
locale: String? = nil // e.g. "en", "fr", "de"
)Open programmatically
Quackback.open() // default view
Quackback.open(board: "feature-requests") // a specific boardListen to events
let token = Quackback.on(.vote) { data in
print("Voted on post:", data["postId"] ?? "")
}
// Stop listening
Quackback.off(token)Event | Payload keys | Description |
|---|---|---|
| - | Widget loaded |
|
| User voted |
|
| User submitted feedback |
| - | Panel dismissed |
Clean up
Quackback.logout() // clear the identity
Quackback.destroy() // tear down the SDKAndroid
Requirements
- Android API 24 or later
- AndroidX
Install with Gradle
Add to your module's build.gradle.kts:
dependencies {
implementation("com.quackback:sdk:0.1.0")
}Configure and identify
// In your Application class
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
Quackback.configure(
context = this,
config = QuackbackConfig(
appId = "your-app-id",
baseURL = "https://feedback.yourapp.com"
)
)
}
}
// After the user signs in; skip identify for anonymous visitors
Quackback.identify(ssoToken = fetchedSsoToken)
// Or, if you know the user at startup, pass the identity to configure:
Quackback.configure(
context = this,
config = QuackbackConfig(appId = "your-app-id", baseURL = "https://feedback.yourapp.com"),
identity = Identity.SsoToken(fetchedSsoToken)
)
// Omit `identity` for anonymous sessions.
// Show the launcher in your Activity
Quackback.showLauncher()Configuration options
Property | Type | Default | Description |
|---|---|---|---|
|
| required | Your Quackback app ID |
|
| required | Your Quackback URL |
|
|
|
|
|
|
|
|
|
|
| Force a language, for example |
Open programmatically
Quackback.open()
Quackback.open(board = "feature-requests")Listen to events
val token = Quackback.on(QuackbackEvent.VOTE) { data ->
Log.d("Quackback", "Voted on: ${data["postId"]}")
}
Quackback.off(token)Clean up
Quackback.logout() // clear the identity
Quackback.destroy() // tear down the SDKLanguage
Both SDKs pass locale to the widget so it renders in the right language from the first frame. If you omit locale, the widget uses the device language. Unsupported languages fall back to English. See Internationalize your widget for the supported languages.
Related articles
Was this helpful?
Your feedback shapes what we write next.
