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 in private beta.
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 pharenlane :beta do
build_app(scheme: "MyApp")
pharen_release # release · dSYMs · build · OTA link
endWith 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.plistinit 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 (npm install -g @pharen-ai/cli), signed in to the organization your approved application created. And either way, the SDK still goes into your app the same three-step way below; that part is already the short version.
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.
Add the package
SDK license. Before obtaining or using the SDK, read its proprietary license (Schedule A, Part C) and the LICENSE.md and LEGAL-TERMS.txt supplied with your selected release. For organizational use, an authorized representative should agree through onboarding or arrange written acceptance with hello@pharen.ai. Automated package resolution is not a record of that agreement.
In Xcode, File → Add Package Dependencies…, or add it to your Package.swift. Pin a SemVer major range.
The package is public: anyone can add it with Swift Package Manager, and the repository is on GitHub. Sending events to Pharen needs an ingest key, which an approved organization mints with the CLI.
dependencies: [
.package(
url: "https://github.com/pharen-ai/pharen-sdk-swift.git",
from: "2.0.0")
]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 organization, 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.
<key>PharenIngestKey</key>
<string>YOUR-INGEST-KEY</string>
<key>PharenConsentGrantedAtBuild</key>
<array>
<string>telemetry</string>
</array>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.
import PharenSDK
import SwiftUI
@main
struct MyApp: App {
init() {
Pharen.start() // reads both values from Info.plist
}
var body: some Scene {
WindowGroup { ContentView() }
}
}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. On plans without white-label the form carries a plain-text “Powered by Pharen” mark once the app has its configuration (a first launch before it arrives shows none); Business and above remove it.
Pharen.crashTest()A deliberate crash, shipped in the SDK, for verifying your pipeline in a Debug build.
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-10-22 for PharenSDK 2.0.0: it adds 4.05 MB to an app’s bundle. On an iPhone 17 Pro running iOS 26.6.1, a tracked event costs 22–24 µs on the calling thread; encoding and the durable write, about 1.3–1.7 ms of CPU, run in the background. App Store download size after thinning is not measured. Events are batched and sent off the main thread, and persisted to disk as queued.
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 live 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.