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.

JM
James Morton
Written By James MortonLast updated 1 day ago

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-ios

Or 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 board

Listen to events

let token = Quackback.on(.vote) { data in
    print("Voted on post:", data["postId"] ?? "")
}

// Stop listening
Quackback.off(token)

Event

Payload keys

Description

.ready

-

Widget loaded

.vote

postId, direction

User voted

.submit

postId, title

User submitted feedback

.close

-

Panel dismissed

Clean up

Quackback.logout()   // clear the identity
Quackback.destroy()  // tear down the SDK

Android

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

appId

String

required

Your Quackback app ID

baseURL

String

required

Your Quackback URL

theme

QuackbackTheme

SYSTEM

LIGHT, DARK, or SYSTEM

position

QuackbackPosition

BOTTOM_RIGHT

BOTTOM_RIGHT or BOTTOM_LEFT

locale

String?

null

Force a language, for example "en" or "fr"

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 SDK

Language

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.

Was this helpful?

Your feedback shapes what we write next.