The SDK

One line of code. Two plist values. That’s the install.

PharenSDK is Swift, distributed with Swift Package Manager, with zero third-party dependencies — Foundation and Apple’s system frameworks only. No config code, no secrets to guard: it configures itself from your Info.plist, and the ingest key is public by design, like a crash-reporter DSN.

iOS today. An Android SDK, built on the same event contract, is on the roadmap.

The fast path

Your release pipeline, in one call.

Registering releases, uploading dSYMs, and minting install links doesn’t need a setup project. Pick whichever matches how you ship:

Already on fastlane

$ fastlane add_plugin pharen
rubyFastfile
lane :beta do
  build_app(scheme: "MyApp")
  pharen_release   # release · dSYMs · build · OTA link
end

With no arguments, pharen_release finds the IPA and dSYMs in the lane context, reads version, build, and bundle id from the IPA’s own Info.plist, and prints the OTA install link. The plugin is MIT-licensed, on RubyGems.

No fastlane? One command sets up the repo

$ pharen init ios --org your-org --app your-app-id
→ wrote .pharen.yml · PHAREN.md · release/release-lane.sh
$ PHAREN_AUTH_TOKEN=… bash release/release-lane.sh
→ archive · symbols upload · builds upload
itms-services://…/manifest.plist

init is purely local — no network, no prompts. It writes your committed config and the canonical release lane; every release after that is the one lane command.

Both paths run on the pharen CLI, provided with your credentials when your application is approved. And either way, the SDK still goes into your app the same three-step way below; that part is already the short version.

By hand

The SDK itself: three steps, about five minutes.

No wizard needed — this is the whole thing, and it’s the same whichever release path you chose.

1 / 3

Add the package

In Xcode, File → Add Package Dependencies…, or add it to your Package.swift. Pin a SemVer major range.

The repository is private today — access comes with your approval, alongside the CLI.

swiftPackage.swift
dependencies: [
    .package(
        url: "https://github.com/pharen-ai/sdk-ios.git",
        from: "2.0.0")
]
2 / 3

Set two Info.plist values

Your ingest key, and the consent purposes you grant at launch. The key ships in your binary and carries no read access — the server derives your tenant, app, and environment from it. Commit it.

No key, no consent — nothing is sent. A missing or placeholder key leaves the SDK completely off: the intended way to disable Pharen in local builds.

xmlInfo.plist
<key>PharenIngestKey</key>
<string>YOUR-INGEST-KEY</string>

<key>PharenConsentGrantedAtBuild</key>
<array>
    <string>telemetry</string>
</array>
3 / 3

Start Pharen

One line, as early as possible in your app’s lifecycle. It installs the crash handlers, starts a session, and begins delivering events in batches, off the main thread. Unconfigured, it returns nil and installs nothing.

swiftMyApp.swift
import PharenSDK
import SwiftUI

@main
struct MyApp: App {
    init() {
        Pharen.start()   // reads both values from Info.plist
    }

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

The surface you’ll actually touch.

Crash capture and sessions run without another line. The rest is small enough to read in a minute.

Pharen.shared?.track(_:properties:)

A named event with optional properties. Behavioral-class — needs behavioral consent.

Pharen.shared?.screen(_:)

A screen view. Same consent class, same envelope, same timeline.

Pharen.shared?.identify(_:traits:)

Connect activity to a known user. Traits route to the restricted attribute store — never onto the event stream, never into logs.

Pharen.shared?.crashReporting.recordError(…)

Handled errors with stack, severity, and breadcrumbs. Telemetry-class, durable queue.

Pharen.shared?.consent.grant(_:) / revoke(_:)

Runtime consent — for example, after your banner returns. Takes effect immediately.

Pharen.shared?.deepLinks.onLink / handle(_:)

Universal-link routing through one hook. Routing fires regardless of consent; the open event reports only the domain the link arrived on — never the path or query string.

Pharen.shared?.presentFeedbackSheet() / presentFeedbackSheet(category:)

The report flow a device shake opens, from your own trigger — a “Send feedback” row in a settings screen. The category: form skips the picker (“Report a problem” opens the problem form). Works whether or not shake is on. Content-class — needs content consent.

Pharen.crashTest()

A deliberate crash, shipped in the SDK, for verifying your pipeline in a Debug build.

Full documentationQuickstart to first crash report: about five minutes.
What it costs the app

Zero third-party dependencies. An empty dependency list. An interface you can read.

One library product, pinned by SemVer major range. The package declares no dependencies — a design decision, not a snapshot — and ships as a compiled framework whose archive is pinned by checksum in the manifest, with its public interface, its documentation, its privacy manifest and its symbols inside. Measured on 2026-09-15 at the package’s iOS 15 floor (the framework built with Xcode 26.0.1; the app with Xcode 26.6 and, in the last sitting, 26.0.1, to the same app-side bytes): adding PharenSDK 1.0.0 to an empty app adds a 1.42 MB framework to the app bundle, before any call is written; the app’s own executable grows by 4.7 KB when it starts the SDK and tracks an event. Download size after App Store thinning is not measurable locally. Per tracked event, measured on 2026-09-15 for 1.0.0, the compiled framework, on an iPhone 17 Pro running iOS 26.6.1: 15–28 µs on the calling thread and 1–3 ms of CPU in the background to encode and durably write it — the ranges of the framework’s three runs across two sittings the same day, because the phone’s state moves both figures more than the code does. Each sitting carried its own control — the same code as a source package in one, the same sources built with the newer compiler in the other — within 1 µs of the framework on the calling thread and inside the run-to-run spread through the write: the compiled framework costs nothing per call. Events are batched and sent off the main thread, and persisted to disk as queued.

And the agent connection

Nothing in the app.

The connection your agent uses is served from the platform, with a key you mint and revoke. The SDK is the whole client footprint: asking about production adds no code, no dependency, and no network call to your app. Connect your agent →

Licensing, plainly: the SDK ships as a compiled framework, licensed under Schedule A of the Terms of Service — licensed, not sold; not open source. What you can read ships with it: the module’s public interface and documentation, the privacy manifest, the consent API, and symbols for every frame. Source is not published; ask, and we will say what can be shown. The integration glue (the fastlane plugin, the release-lane template) is MIT.