iOS & macOS

Native Swift SDK for iOS and macOS - signal + NSException crash capture with Mach-O image tracking for dSYM symbolication, app-hang detection, sessions, breadcrumbs and logs.

Requirementslink

  • iOS 14+ (CocoaPods or Swift PM) · macOS 11+ (Swift PM) · Swift 5.9 / Xcode 15+
  • Depends only on system frameworks (Foundation, Combine, Network) + CryptoKit/swift-crypto

1 - Installlink

Swift Package Manager:

.package(url: "https://github.com/New-Instance-Org/bug-watch-ios.git", from: "0.1.0")

CocoaPods:

pod 'BugWatch', '~> 0.1'

2 - Initialise (as early as possible)link

import BugWatch

@main
struct MyApp: App {
    init() {
        BugWatch.start(options: BugWatchOptions(
            projectId: Secrets.bugwatchProjectId,
            appSecret: Secrets.bugwatchAppSecret,
            environment: "production",
            release: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0"
        ))
    }
    var body: some Scene { WindowGroup { ContentView() } }
}

Inject the credentials via an .xcconfig/build setting - keep them out of source control.

3 - Configuration optionslink

OptionDefaultWhat it does
environment / releaseproduction / -Labels; release must match dSYM uploads' metadata
sampleRate1.0Client-side sampling
autoSessionTrackingtrueRelease-health sessions
enableAppHangTracking / appHangThresholdMstrue / 2000Main-thread hang detector
enableAutoBreadcrumbstrueLifecycle breadcrumbs
enableNetworkBreadcrumbs + allow/deny hoststrueURLSession breadcrumbs (BugWatch's own ingest calls are excluded)
sensitiveFieldsbuilt-in listExtra redaction keys
batchSize / flushIntervalMs / maxQueueSize50 / 5000 / 1000Delivery + offline queue (persisted in Application Support)

4 - Capture APIlink

BugWatch.capture(error)
BugWatch.captureMessage("Sync finished", level: .info)
BugWatch.setUser(User(id: "u_123", email: "ada@example.com"))
BugWatch.setTag("tenant", value: "acme")
BugWatch.setContext("payment", value: ["provider": "paystack"])
BugWatch.addBreadcrumb("Tapped checkout")
BugWatch.flush()

Automatic capturelink

  • Crashes - POSIX signal handlers + NSSetUncaughtExceptionHandler, recorded with the process's Mach-O binary images (UUID + load address per frame) so the backend symbolicates against your dSYMs. The crash report ships on next launch.
  • App hangs - main-thread stalls beyond the threshold become events with the hanging stack.
  • Delivery is network-aware (NWPathMonitor): offline events wait; nothing is dropped until the queue cap.

5 - Symbolication (CI, macOS runner)link

npx @newinstance/bugwatch-cli symbols upload MyApp.xcarchive \
  --release "$MARKETING_VERSION" --build-number "$BUILD_NUMBER" \
  --distribution app-store --token "$BUGWATCH_CI_KEY"

Accepts .xcarchive, .dSYM bundles, zips of dSYMs, or raw Mach-O files; requires zip on PATH. Matching is by debug UUID, so bitcode-recompiled or multi-machine builds all resolve. Poll Source Maps & Symbols → Get upload status until DONE, then Reprocess any crashes that arrived early.

Troubleshootinglink

  • Crash reports missing → crashes upload on the next launch; force-quit during upload delays to the launch after. Check the device clock (>60 s skew rejects tokens).
  • Frames show addresses, not symbols → dSYM for that exact build UUID not indexed; DONE status yet? App-store builds need the archive's dSYMs (not the simulator build's).
  • TestFlight vs App Store confusion → pass --distribution so the dashboard separates them.

The request below is the exact wire call the SDK makes, including payloadVersion: 2 with binaryImages + nativeStacktrace.