🍎

iOS SDK

Integrate SecureInspector into your iOS app for privacy-first debugging with end-to-end encryption.

1 Installation

Swift Package Manager

Add the package to your Xcode project:

// In Xcode: File > Add Packages...
// Enter the repository URL:
https://github.com/secureinspector/ios-sdk

Or add to Package.swift

dependencies: [
    .package(url: "https://github.com/secureinspector/ios-sdk", from: "1.0.0")
]

2 Initialization

Initialize the SDK in your AppDelegate or App struct:

import SecureInspector

@main
struct MyApp: App {

    init() {
        let config = SecureInspectorConfig(
            serverURL: "https://your-server.com",
            apiKey: "your-api-key",
            encryptionKey: "your-base64-encryption-key"
        )

        SecureInspector.shared.initialize(with: config)
    }

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

UIKit (AppDelegate)

import SecureInspector

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        let config = SecureInspectorConfig(
            serverURL: "https://your-server.com",
            apiKey: "your-api-key",
            encryptionKey: "your-base64-encryption-key"
        )

        SecureInspector.shared.initialize(with: config)

        return true
    }
}

3 HTTP Capture

HTTP traffic is captured automatically using URLProtocol interception. For URLSession with custom configuration:

// Use the pre-configured URLSession
let sessionConfig = SecureInspector.shared.getURLSessionConfiguration()
let session = URLSession(configuration: sessionConfig)

// All requests through this session are captured
session.dataTask(with: url) { data, response, error in
    // Handle response
}.resume()

4 User Identification

Set the user ID after login:

// After successful login
SecureInspector.shared.setUserId("user@example.com")

// On logout
SecureInspector.shared.clearUserId()

5 Crash Handling

The SDK automatically captures:

  • Uncaught NSExceptions
  • Swift fatal errors
  • Signal crashes (SIGSEGV, SIGABRT, etc.)
  • Mach exceptions (EXC_BAD_ACCESS)

Crash context includes:

  • Full stack trace with symbolication
  • Device information
  • Memory state at crash
  • Recent breadcrumbs
  • Recent HTTP calls

6 Error Capture

Manually capture handled errors:

do {
    try riskyOperation()
} catch {
    SecureInspector.shared.captureError(
        error,
        message: "Failed to process payment",
        context: [
            "orderId": orderId,
            "amount": String(amount)
        ]
    )
}

7 Custom Events

Track custom events with properties:

SecureInspector.shared.captureEvent(
    name: "purchase_completed",
    properties: [
        "product_id": "SKU123",
        "price": 99.99,
        "currency": "EUR"
    ],
    level: .info
)

9 Mobile Vitals

Automatically captured performance metrics:

Startup Time

Cold start, warm start detection and timing

Frame Rate

CADisplayLink-based frame monitoring

Memory

Memory warnings and usage tracking

Hang Detection

Main thread blocked detection (5s threshold)

10 WebView Support

Capture WKWebView navigation (opt-in feature):

// 1. Enable in config
var config = SecureInspectorConfig(...)
config.captureWebView = true

// 2. Wrap your WKWebView
let webView = WKWebView(frame: .zero)
SecureInspector.shared.wrapWebView(webView)

// Or with existing delegate
SecureInspector.shared.wrapWebView(webView, delegate: myDelegate)

11 Logging Integration

SecureLogger

Built-in logger that outputs to OSLog and SecureInspector:

// Create a logger for your module
let logger = SecureInspector.shared.createLogger(category: "Network")

// Use it like OSLog
logger.debug("Request started")
logger.info("Response received")
logger.warning("Slow response")
logger.error(error, "Request failed")  // Auto-captured!

CocoaLumberjack Integration

// Enable CocoaLumberjack capture (if available)
SecureInspector.shared.enableCocoaLumberjackCapture()

// Now DDLogError() calls with exceptions are captured

12 Configuration Options

var config = SecureInspectorConfig(
    serverURL: "https://your-server.com",
    apiKey: "your-api-key",
    encryptionKey: "your-encryption-key"
)

// Session polling
config.sessionCheckInterval = 30  // seconds

// Max body size for HTTP capture
config.maxBodySize = 1024 * 1024  // 1MB

// Exclude URLs
config.excludeURLPatterns = [".*analytics.*", ".*tracking.*"]

// Custom sensitive headers
config.sensitiveHeaders = ["X-Custom-Auth"]

// Custom sensitive fields
config.sensitiveFields = ["ssn", "taxId"]

// Feature toggles
config.captureHTTP = true
config.captureCrashes = true
config.captureVitals = true
config.detectHangs = true
config.captureScreens = true
config.captureUserInteractions = true
config.captureWebView = false  // opt-in

// Debug mode
#if DEBUG
config.debugMode = true
#endif

// Error callback
config.errorCallback = { error in
    print("SecureInspector error: \(error)")
}

SecureInspector.shared.initialize(with: config)

API Reference

SecureInspector.shared.initialize(with: config)

Initialize the SDK. Call on app launch.

SecureInspector.shared.setUserId(_:)

Set current user ID (after login).

SecureInspector.shared.clearUserId()

Clear user ID (on logout).

SecureInspector.shared.captureError(_:message:context:)

Manually capture a handled error.

SecureInspector.shared.captureEvent(name:properties:level:)

Capture a custom event with optional properties.

SecureInspector.shared.addBreadcrumb(category:message:data:)

Add a custom breadcrumb.

SecureInspector.shared.isCapturing

Check if a debug session is currently active.

SecureInspector.shared.flushCaptures()

Force send all pending captures.

SecureInspector.shared.clearLocalData()

Delete all locally stored captures.

SecureInspector.shared.shutdown()

Shutdown the SDK and release resources.

Need Help?

Having trouble integrating? Our team is here to help you get started.

Contact Support