Skip to content
On this page

Guides

iOS (ShipbellKit)Coming soon

ShipbellKit is a Swift package with a native problem sheet, and links that open your board.

Requirements

  • iOS 17 or later
  • Swift 6 language mode
  • No dependencies. Your app passes in its own Sentry event ids
  • A privacy manifest, PrivacyInfo.xcprivacy, ships with the package

InstallComing soon

Add the package with Swift Package Manager. Its repository, shipbell-ios, has Package.swift at the root.

ConfigureComing soon

Configure ShipbellKit when your app starts. tokenProvider returns a token from your backend, or nil when the user is signed out. context is read when a report is sent.

Swift
ShipbellKit.configure(
    projectKey: "sb_pk_live_…",
    host: URL(string: "https://api.shipbell.app")!,
    tokenProvider: { try await auth.feedbackToken() },
    context: { await FeedbackContext.current() }
)
ShipbellKit.setUser(userID)

view.feedbackSheet(isPresented: $show)
ShipbellKit.openBoard(.ideas)
CallWhat it does
setUser(_:)Drops the session when the user changes, and keeps queued reports apart per user
recordError(operation:category:detail:sentryEventID:)Adds an entry to the recent errors that go with a report
feedbackSheet(isPresented:)Shows the problem sheet
feedbackRedacted()Hides a view in the screenshots the kit takes
present(captureScreen: true)Opens the sheet with a screenshot, for contextual entry points only
openBoard(_:)Opens .ideas, .roadmap, .problems, .newPost or .myReports, signed in
unreadCountAn observable count of unread updates, for a badge
enableScreenshotPrompt(isAllowed:)Offers to report a problem after the user takes a screenshot, whenever isAllowed returns true

The problem sheet

  • A "Sending as" row, a text editor and "Attach screenshot" through the photo picker, which needs no photo permission.
  • "Who can see this report?", with a public and a private choice preselected from your project's settings, or one line when every report is private.
  • "Included with your report (only the team sees this)", which lists what is sent.
  • The number of reports waiting to send, when there are any.

A sheet with unsent text asks before it closes. It supports Dynamic Type and VoiceOver, and its wording matches the web widget.

Open the board

openBoard opens your board, already signed in, in SFSafariViewController. The sheet shows a link to each part of the board only when that part is on for your project.

Screenshots

ShipbellKit takes a screenshot only from a contextual entry point: an error banner, present(captureScreen: true) or the screenshot prompt. It draws the key window before its own sheet appears, paints over every view marked with .feedbackRedacted(), and always shows a preview with Remove.

Reports sent later

  • A report that cannot be sent waits in an outbox on the device, protected until the first unlock and left out of backups.
  • Each report's id is its Idempotency-Key, so a retry never files it twice.
  • Queued reports belong to the user who wrote them, and are sent only while that user is signed in.
  • The kit retries when the network returns, when the app becomes active and after setUser.
  • Reports expire after 30 days. The outbox holds at most 20 reports or 10 MB.

What ShipbellKit collects

  • App version, build number and bundle id
  • System name and version, model identifier and device idiom, and whether it runs on a Mac
  • Locale, preferred language and time zone
  • Text size, VoiceOver, Reduce Motion and colour scheme
  • Low Power Mode and thermal state
  • Network status, and whether the connection is expensive or constrained
  • The ShipbellKit version

It avoids every API that needs a required reason, and collects no advertising or vendor identifier.

Privacy manifest

The manifest declares no tracking and no tracking domains. It lists these data types, all linked to the user, none used for tracking, all for app functionality: customer support, other diagnostic data, user ID, email address, name (only when you send names), photos or videos, and other user content.

You still update your App Store Connect privacy labels yourself.

Failing open

ShipbellKit never blocks your app from starting, and gives up on a request after 5 seconds. It follows the minimum client version and the kill switch in your project's configuration.