iOS
Errora works with the official Sentry Cocoa SDK
unchanged. The SDK captures crashes on-device, reports app hangs and watchdog terminations, and
sentry-cli uploads the dSYMs Errora needs to turn crash addresses into function names, files
and lines.
Create the project with the iOS platform so the UI shows the right snippets.
Install
Swift Package Manager — in Xcode, File → Add Package Dependencies…, then:
https://github.com/getsentry/sentry-cocoa
CocoaPods:
# Podfile
pod 'Sentry'
Initialize
Start the SDK as early as possible — in application(_:didFinishLaunchingWithOptions:), or
the init() of your SwiftUI App:
import Sentry
SentrySDK.start { options in
options.dsn = "https://<public_key>@<your-errora-host>/<project_id>"
options.environment = "production"
options.tracesSampleRate = 0.2 // tracing
options.configureProfiling = { // profiling
$0.sessionSampleRate = 1.0
$0.lifecycle = .trace
}
options.attachScreenshot = true // screenshot on error
options.attachViewHierarchy = true // view hierarchy on error
options.sessionReplay.onErrorSampleRate = 1.0
options.sessionReplay.sessionSampleRate = 0.1
options.enableAppHangTracking = true // default: on
options.appHangTimeoutInterval = 2 // seconds
}
Older SDK versions configure profiling with options.profilesSampleRate = 1.0 instead of
configureProfiling; Errora accepts what either sends.
Options worth enabling
| Option | What you get in Errora |
|---|---|
tracesSampleRate | Performance: app start, UIViewController, network spans |
configureProfiling / profilesSampleRate | Profiling, symbolicated with your dSYMs |
attachScreenshot | A screenshot stored with each error, previewed on the issue page |
attachViewHierarchy | The view tree at the moment of the error, rendered as a tree on the issue page |
sessionReplay.*SampleRate | Mobile session replay |
enableAppHangTracking | App hangs arrive as ordinary errors and group/alert like any issue |
enableAutoSessionTracking | Sessions for release health — on by default |
You don't need to set a release: the SDK uses <bundleId>@<version>+<build> automatically,
and that is the string release health keys on.
Screenshots, view hierarchies and Apple crash reports are attachments: stored with their event, kept for the organization's data retention, and dropped with the event when it is sampled out or spike-limited.
Upload dSYMs
A crash report holds instruction addresses. Errora symbolicates them before grouping with the dSYM whose debug id (Mach-O UUID) matches each loaded image — see Debug files.
1. Produce dSYMs
In the target's Build Settings, set Debug Information Format to DWARF with dSYM File — at least for the Release configuration.
2. Configure sentry-cli
Install sentry-cli (brew install getsentry/tools/sentry-cli) and give it Errora's address.
Either environment variables:
export SENTRY_URL=https://<your-errora-host>
export SENTRY_AUTH_TOKEN=errora_pat_…
export SENTRY_ORG=<organization-slug>
export SENTRY_PROJECT=<project-slug>
…or a .sentryclirc next to the project (keep the token out of git):
[defaults]
url = https://<your-errora-host>
org = <organization-slug>
project = <project-slug>
[auth]
token = errora_pat_…
The token is an Errora personal access token whose owner is a
member (or higher) of the organization. The organization slug is the one in your dashboard
URL (/organizations/<slug>/…).
3. Add an Xcode build phase
Build Phases → + → New Run Script Phase, placed after Compile Sources:
if [[ "$(uname -m)" == arm64 ]]; then
export PATH="/opt/homebrew/bin:$PATH"
fi
if which sentry-cli >/dev/null; then
ERROR=$(sentry-cli debug-files upload "$DWARF_DSYM_FOLDER_PATH" 2>&1 >/dev/null)
if [ ! $? -eq 0 ]; then
echo "warning: sentry-cli - $ERROR"
fi
else
echo "warning: sentry-cli not installed"
fi
Add this to the phase's Input Files so Xcode runs it after the dSYM exists (and so it works with user script sandboxing):
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}
Or with fastlane
lane :upload_symbols do
sentry_debug_files_upload(
url: "https://<your-errora-host>",
auth_token: ENV["SENTRY_AUTH_TOKEN"],
org_slug: "<organization-slug>",
project_slug: "<project-slug>",
)
end
Run it after build_app (or gym), so the build's dSYMs are on disk.
You can also upload a debug file by hand from the browser, under Settings → Debug files.
Verify
Build a Release configuration, run the app without the debugger attached (the debugger swallows crashes), then:
SentrySDK.capture(error: NSError(domain: "errora.smoke-test", code: 1))
// or crash for real:
SentrySDK.crash()
A crash is sent the next time the app launches. Open the issue: frames should show function names, files and lines, with inlined frames expanded. If a frame isn't symbolicated, the issue page lists the missing debug id and the image it belongs to.
Troubleshooting
| Symptom | Cause / fix |
|---|---|
| Frames show only addresses | The dSYM for that build wasn't uploaded — check the build log and Debug files |
Swift symbols look like $s7MyApp… | The Errora image demangles Swift with the bundled Swift runtime; a custom image needs libswiftCore.so — see Debug files |
No crash after SentrySDK.crash() | The debugger was attached, or the app wasn't relaunched |
Upload fails with 401 | Wrong or revoked token, or SENTRY_URL isn't set (sentry-cli defaults to sentry.io) |
| No release health data | enableAutoSessionTracking was turned off |