Quickstart
iOS SDK

iOS SDK Quickstart

Install the Gleam Swift package, configure the SDK, start the session, then present the Portal or call SDK APIs for custom feedback, announcement, and notification screens.

Last reviewed June 2, 2026

Use An AI Agent First

Using Codex, Cursor, Claude Code, or another coding agent? Start with the AI Agent Prompt page and let the agent add Gleam to your app.

Requirements

The Gleam iOS SDK is distributed as a Swift Package and supports iOS 15 or later. The public product target is named GleamSDK.

RequirementValue
Package URLhttps://github.com/Gleam-land/gleam-ios-sdk.git
Minimum iOSiOS 15

Install With Swift Package Manager

In Xcode, open File -> Add Package Dependencies, paste the package URL, and link the GleamSDK product to your app target.

Package URL

https://github.com/Gleam-land/gleam-ios-sdk.git

Configure And Start

Initialize the SDK once during application startup. The project ID and SDK key are client-safe values from Settings -> Integrations in the Gleam dashboard.

Call start() before presenting Portal UI or using SDK APIs. It resolves the hosted Portal URL, creates or restores the no-login session, checks what the server supports, and prepares the WebView and Data API paths used by the SDK.

Application startup

Choose the app lifecycle your iOS app already uses.

Configure once in the App initializer, then start the SDK session asynchronously.
import SwiftUI
import GleamSDK

@main
struct MyApp: App {
  init() {
    do {
      try Gleam.shared.configure(
        GleamConfiguration(
          projectId: "YOUR_PROJECT_ID",
          apiKey: "YOUR_GLEAM_SDK_KEY"
        )
      )

      #if DEBUG
      Gleam.shared.setLogLevel(.debug)
      #endif

      Task {
        try await Gleam.shared.start()
      }
    } catch {
      assertionFailure("Failed to configure Gleam: \(error)")
    }
  }

  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

Present The Portal

Use the SwiftUI full-screen view for a native presentation, or call the UIKit convenience methods from an existing view controller.

Portal presentation

Use the same project configuration; only the presentation layer changes.

Present the hosted Portal with a full-screen SwiftUI cover.
import SwiftUI
import GleamSDK

struct ContentView: View {
  @State private var showFeedback = false

  var body: some View {
    Button("Send Feedback") {
      showFeedback = true
    }
    .fullScreenCover(isPresented: $showFeedback) {
      GleamPortalFullScreenView(section: .feedback)
    }
  }
}

Build A Native Feedback UI

If you want a fully native SwiftUI or UIKit feedback board, use the feedback Data API after start() succeeds instead of presenting the hosted Portal WebView.

Anonymous sessions work by default, so users can fetch, submit, vote, and comment without creating a separate Gleam login screen. The server still owns moderation, visibility, and follow-up state.

Native feedback flow

Use the Portal preset for the official H5 experience. Use these methods when the app owns the feedback UI.

try await Gleam.shared.start()

let page = try await Gleam.shared.fetchFeedback(limit: 20)
let firstBoardId = page.boards.first?.id

let post = try await Gleam.shared.submitFeedback(
  title: "Add dark mode",
  content: "The editor is too bright at night.",
  boardId: firstBoardId
)

let votedPost = try await Gleam.shared.setFeedbackVote(
  postId: post.id,
  voted: true
)

try await Gleam.shared.addFeedbackComment(
  postId: votedPost.id,
  body: "I can help test this."
)

Build Custom Updates And Notifications

The SDK also exposes announcement and notification APIs for apps that want their own in-app update center instead of routing every update through the Portal UI.

Use announcements for public or targeted product updates, notifications for user-specific follow-up, preferences for reply and announcement controls, and APNs routing when a push should open a precise Portal destination.

Custom update center

Use these APIs when the app owns the announcement feed, unread inbox, or notification settings UI.

try await Gleam.shared.start()

let announcements = try await Gleam.shared.fetchAnnouncements()
let latest = try await Gleam.shared.fetchLatestAnnouncements()

let notifications = try await Gleam.shared.fetchNotifications(
  limit: 20,
  unreadOnly: false
)

let preferences = try await Gleam.shared.getNotificationPreferences()
try await Gleam.shared.setNotificationPreferences(
  GleamNotificationPreferences(
    notifyIosPushReply: preferences.notifyIosPushReply,
    notifyIosPushAnnouncement: true
  )
)

Release Check

Before shipping the SDK entry point to users, test the flow from the real app screen where feedback, announcements, or notifications will live. The quickstart code proves the SDK can open, but your product still owns placement, permission timing, and the fallback state when a network request fails.

Most apps launch with the Portal UI first, then add signed identity, notification polling, and APNs registration as separate steps. That sequence keeps the first release small and makes each integration issue easier to isolate.

1

Open feedback from a real navigation point

Use the settings screen, help screen, or contextual feedback button your users will actually tap. Confirm the Portal opens and dismisses cleanly on simulator and device.

2

Verify anonymous and signed-in behavior

Start without signed identity, submit a request, then add identity only after your backend token endpoint is ready. Confirm the app never stores the identity secret client-side.

3

Handle setup and network errors

Catch SDK errors, show a clear fallback, and keep the app usable if the Portal descriptor cannot be fetched during startup.

Next Steps