iOS SDK
v1.6.0Integrate BugScreen into your iOS app in minutes. Swift, SwiftUI, UIKit, SPM.
Sample app
BugScreen Travel is a small SwiftUI app that wires up every integration point, with all SDK calls behind an #if DEBUG facade so nothing ships to release.
Installation
Swift Package Manager
In Xcode, choose File → Add Package Dependencies… and enter the repository URL:
https://github.com/bugscreenapp/bugscreen-iosOr add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/bugscreenapp/bugscreen-ios", from: "1.6.0")
]CocoaPods
Add BugScreenSDK to your Podfile:
pod 'BugScreenSDK', '~> 1.6'Then run pod install.
Requires iOS 15.0+ and Swift 5.9+.
Setup
BugScreen is for dev/QA, so keep it out of what your end users get. Pick the approach that fits your setup:
No-op pod — keep BugScreen out of release builds (CocoaPods)
The cleanest option if you use CocoaPods: ship the real SDK on Debug and the BugScreenSDK-NoOp stub on Release. The stub vends the same BugScreenSDK module with empty implementations, so your call sites compile unchanged — and no BugScreen code, resource bundle, or PrivacyInfo.xcprivacy declarations ship in your production binary.
pod 'BugScreenSDK', '~> 1.6', :configurations => ['Debug']
pod 'BugScreenSDK-NoOp', '~> 1.6', :configurations => ['Release']Then call BugScreenSDK.configure(...) with no guard — release builds resolve the no-op and do nothing.
#if DEBUG guard alone isn't enough.Exclude BugScreen from release builds (SPM)
SPM can't swap dependencies per configuration, but you can still keep BugScreen out of release builds entirely. On your app target's build settings, add the BugScreenSDK* pattern to Excluded Source File Names for every non-Debug configuration, and keep your calls behind the #if DEBUG guard below. The pattern matches the BugScreenSDK package, dropping the whole product from your app's link and resource-copy steps — so release builds link no BugScreen code and ship no resource bundle or PrivacyInfo.xcprivacy.
EXCLUDED_SOURCE_FILE_NAMES = BugScreenSDK*#if DEBUG is inactive there too. Verified on Xcode 26; check a release build's bundle after wiring it up.#if DEBUG guard
Compiles out your call sites. On SPM this alone does not remove the SDK — its code, resource bundle, and PrivacyInfo.xcprivacy still ship in release unless you also apply the exclusion above (or, on CocoaPods, the no-op pod).
import SwiftUI
#if DEBUG
import BugScreenSDK
#endif
@main
struct MyApp: App {
init() {
#if DEBUG
BugScreenSDK.configure(
apiKey: "fb_your_api_key_here",
enableScreenshotDetection: true
)
#endif
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}import UIKit
#if DEBUG
import BugScreenSDK
#endif
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
#if DEBUG
BugScreenSDK.configure(
apiKey: "fb_your_api_key_here",
enableScreenshotDetection: true
)
#endif
return true
}
}Tester-flag guard
Runs on production builds for users you flag as testers — useful for dogfooding.
import SwiftUI
import BugScreenSDK
@main
struct MyApp: App {
init() {
// currentUser.isTester is pseudocode — replace with your tester signal.
if currentUser.isTester {
BugScreenSDK.configure(
apiKey: "fb_your_api_key_here",
enableScreenshotDetection: true
)
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Photo Library Access (Recommended)
Add this to your Info.plist so BugScreen can auto-attach the screenshot the user just took, and so users can pick screenshots manually:
<key>NSPhotoLibraryUsageDescription</key>
<string>Attach screenshots to bug reports to help us fix issues faster</string>Usage
Automatic screenshot detection
When users take a screenshot, BugScreen automatically presents the bug report UI. No additional code required. Reporters can attach up to four screenshots to a single report from the in-app sheet.
Manual triggering (SwiftUI)
Present the bug report screen programmatically:
Button("Report Bug") {
BugScreenSDK.presentBugReport()
}
// With pre-attached screenshot
Button("Report with Screenshot") {
BugScreenSDK.presentBugReport(screenshot: myImage)
}Manual triggering (UIKit)
@IBAction func reportBugTapped(_ sender: UIButton) {
BugScreenSDK.presentBugReport(from: self)
}
// With screenshot
BugScreenSDK.presentBugReport(
from: self,
screenshot: myImage
)Logging
Add context to bug reports with application logs:
BugScreenSDK.log("Detailed debug info", level: .verbose)
BugScreenSDK.log("Debug message", level: .debug)
BugScreenSDK.log("User tapped checkout button", level: .info)
BugScreenSDK.log("Network request took longer than expected", level: .warning)
BugScreenSDK.log("Payment failed: \(error.localizedDescription)", level: .error)Logs are automatically included with every bug report. The SDK maintains a 1 MB circular buffer of the most recent logs.
Custom data
Attach arbitrary key/value pairs to every subsequent bug report:
// Replace the whole map:
BugScreenSDK.setCustomData([
"env": "staging",
"buildType": "debug",
"userTier": "pro",
])
// Set or remove a single key:
BugScreenSDK.setCustomData(key: "userId", value: "abc-123")
BugScreenSDK.removeCustomData(key: "userId")
// Merge a map without replacing existing keys:
BugScreenSDK.addCustomData(["plan": "pro", "region": "eu"])
// Remove all custom data:
BugScreenSDK.clearCustomData()Call any time after configure() from the main actor. The values are read when the bug report screen opens and appear in the report's metadata.
User accounts
Identify the account a report is filed under so a triager can reproduce the bug. It renders as a dedicated Account section at the top of the created issue, and the role becomes a filterable label.
// Set the current account (id required; role and email optional):
BugScreenSDK.setUser(id: "pro-user-8823", role: "admin")
// Or read it fresh at capture time — ideal when QA switches logins mid-session:
BugScreenSDK.setUserProvider {
session.currentUser.map { BugScreenUser(id: $0.id, role: $0.role) }
}
// Clear it on logout:
BugScreenSDK.clearUser()Only role becomes a label (non-PII); id and email stay in the issue body. Pass email only when you want a contactable address in the tracker — nothing is auto-collected.
Configuration
| Option | Default | Description |
|---|---|---|
| apiKey: String | Required | Your API key from the BugScreen console (must start with "fb_") |
| enableScreenshotDetection: Bool | true | Auto-detect screenshots and present bug report UI |
| debug: Bool | false | Enable SDK debug behavior (gate with #if DEBUG) |
What gets collected?
BugScreen automatically collects this information with each report:
- •Device model (e.g. Apple iPhone16,1)
- •iOS version
- •App version & build number
- •Bundle identifier
- •Screen size (points and pixels) & scale
- •Memory (total & available)
- •Device locale
- •Appearance (dark / light)
Start shipping bug reports
Create an account to start shipping bug reports from your app.