Skip to content
anecticoDocsDashboard
Browse documentation
Reference

iOS SDK API

Functions, options, parameters, return values, and propagation helpers for the Anectico Swift SDK.

On this page

This is the public Swift API for the native Anectico iOS SDK. It supports iOS 15 and later. configure throws AnecticoConfigurationError for invalid options; telemetry calls made before configuration remain safe no-ops with a log warning. Event/error network work runs off the calling thread.

Use a project key with ingest:write and analytics:write. The native SDK does not record replay.

Configure the SDK

import Anectico

try Anectico.configure(
    AnecticoOptions(
        apiKey: "an_...",
        environment: "production",
        release: "com.acme.Shop@2.4.1+318",
        dist: "318"
    )
)
API Parameters Returns Behavior
Anectico.configure(options) AnecticoOptions throws; Void Validates options, then configures identity, sessions, event queue, error transport, crash handlers, lifecycle hooks, and timers. If the app is already active, emits its missed $app_opened exactly once. Repeated calls are ignored; calls while shutdown is still draining throw. Ordinary configuration preserves analytics withdrawal across restart.
Anectico.flush(completion:) callback taking Bool Void Starts an asynchronous diagnostic-event flush and hands the completion whether every batch it attempted was accepted. See Knowing whether your events arrived.
Anectico.shutdown(completion:) callback taking Bool Void Stops timers/hooks, flushes queued events, releases state, and permits reconfiguration after its completion fires. The completion carries the final flush's outcome, like flush.
Anectico.disableAnalytics() — Bool Stops analytics admission/retries and persists withdrawal. true confirms the withdrawal marker and queue purge; see below for failure handling.
Anectico.configure(options, resumeAnalyticsCollection: true) AnecticoOptions; explicit renewed consent throws; Void After shutdown completion, purges withdrawn events before clearing the marker and creating a fresh client.
Anectico.stats() — AnalyticsStats? Delivery counters — recorded, delivered, dropped, queued — or nil before configure.
Anectico.onDeliveryError(_:) handler taking DeliveryError, or nil Void Registers a handler called once per permanently discarded batch with status, dropped, and reason. Safe to call before configure.

Knowing whether your events arrived

flush answers one question: was everything the SDK had queued accepted? It reports success only when every batch it attempted was accepted, and finding an empty queue is a success — nothing was left unaccepted. Errors and crash reports travel their own pipeline and are not covered by this answer.

A failure has two shapes, and Anectico.stats() separates them:

What happened Your events flush stats()?.queued drop callback
Permanently rejected — a bad request, or a key that is revoked, wrong, or missing the analytics:write scope discarded, never retried failure excludes refused positions fires once
Temporarily unavailable — no network, rate limited, or a server error still queued for the next flush failure includes them silent

Anectico.stats() reports recorded, delivered, dropped, and queued, and recorded always equals the other three added together. delivered counts positions acknowledged queued in a complete version-one capture ledger, not unique stored rows or immediate query visibility. queued includes in-flight events. A mixed receipt retires queued and explicitly refused positions while preserving uncertain original IDs, timestamps, identities and payloads ahead of unsent events. The durable spool retains those uncertain events for recovery after restart. Malformed, oversized (over 64 KiB), incomplete or contradictory receipts at any HTTP status retain the entire affected chunk. HTTP 200 alone cannot claim delivery, and an untyped HTTP 4xx cannot authorize a drop. Without a server hint, consecutive uncertain attempts back off from one second, doubling up to 60 seconds and resetting after a fully settled receipt; server Retry-After hints are capped at 60 seconds. The default HTTP attempt has a 15-second wait bound. OTLP error and crash delivery uses its separate transport policy.

Session and identity changes remain effective in memory when local persistence fails. Logging out rotates both identities even if storage cannot be cleared; a backward clock change starts a new session. Property serialization stops at depth 32 and emits [MaxDepth] for deeper values. HTTP redirects are rejected so event credentials are sent only to the configured endpoint.

Anectico.onDeliveryError(_:) fires once per discarded batch with the response HTTP status (including 200 for ledger refusals), how many events were lost, and a stable lower-case reason. Ledger refusals use invalid_event, quota_exceeded, or mixed_rejection when one chunk has multiple refusal causes. Typed request refusals use bad_request, unauthorized, forbidden, or payload_too_large. Local drops report status 0: queue_overflow (the queue filled up and the oldest events were evicted) and not_serializable (an event's properties could not be encoded). collection_disabled marks withdrawal of pending or uncertain positions. A temporary failure alone does not fire it. The handler runs outside the queue and bookkeeping locks, on the caller thread for local drops or the flush dispatcher for delivery outcomes.

Capturing does not wait for network delivery: capture, identify, group, and screen serialize and persist the queued event, then return, so the delivery outcome reaches you through the three signals above and never through their own return value.

Anectico.onDeliveryError { error in
    print("lost \(error.dropped) events: \(error.reason.rawValue) (HTTP \(error.status))")
}

Anectico.flush { accepted in
    if !accepted, let stats = Anectico.stats() {
        // stats.queued > 0 means a retry is pending; otherwise the events are gone.
    }
}

Withdraw analytics collection

Call Anectico.disableAnalytics() when analytics consent is withdrawn. It blocks subsequent capture, screen, identify, group and analytics reset operations, stops the periodic analytics timer, discards pending events, and records collection_disabled with status 0. SDK lifecycle events also stop being admitted. Identity and group state are not changed by refused analytics calls. The method performs synchronous local disk I/O but does not wait for network delivery, so a delivery error callback may invoke it safely. Use flush(completion:) outside that callback to observe final counters after an already-admitted request settles.

Already-admitted requests may finish. Validated queued/refused receipt positions keep their actual outcomes; uncertain positions and later unsent chunks are discarded without retry. A discarded uncertain event may already have reached the server. Withdrawal neither erases remote data nor stops the separate error, crash and OTLP producers.

The returned Bool confirms both the persisted withdrawal marker and deletion of the analytics spool. If it is false, collection still stops in this configured process, but disk cleanup or marker persistence failed: retry disableAnalytics() and do not assume restart safety until it returns true. Calling it before configuration returns false. Repeated calls retry the disk operation without reopening admissions or double-counting discarded events.

Ordinary configure(options) respects the durable marker after a restart. Only after obtaining new consent should the application wait for shutdown completion, then call try Anectico.configure(options, resumeAnalyticsCollection: true). Renewal removes the old spool even if the marker is absent before clearing the marker; filesystem failure throws and leaves the SDK unconfigured. Never set that argument automatically on every launch. React Native and Flutter expose corresponding awaited disableAnalytics and explicit renewed-consent configuration controls; see their SDK references.

AnecticoOptions

Only apiKey is required. Invalid endpoints, timers, capacities, frame limits, and non-finite or out-of-range sampling values throw AnecticoConfigurationError rather than being clamped.

Option Type/default Purpose
apiKey String; required Key sent to error and event endpoints.
endpoint String; https://api.anectico.com Base URL for /v1/traces and /api/v1/capture.
environment String; development deployment.environment resource value.
release String?; service version when real Regression and symbol-artifact identifier.
dist String; empty Build/artifact discriminator.
serviceName String?; bundle ID service.name.
serviceVersion String?; bundle marketing version service.version.
flushAt Int; 20 Event-count flush threshold.
flushIntervalMs Int; 5000 Foreground-only periodic event flush; zero disables the timer.
maxStackTraceFrames Int; 50 Maximum frames per error.
breadcrumbCapacity Int; 100 Ring-buffer capacity.
maxQueueSize Int; 10000 Diagnostic-event queue cap; oldest entries drop at the cap.
errorSampleRate Double; 1 Non-fatal error sampling in the inclusive range 0–1.
enableCrashReporting Bool; true Install uncaught NSException and fatal-signal handlers.
debug Bool; false Emit SDK diagnostics through Apple logging.

Identity, accounts, and events

Method/property Parameters Returns Behavior
Anectico.identify(distinctId, set:) stable ID; optional person properties Void Links the anonymous ID to a known person and queues identify.
Anectico.group(type:key:set:) account type/key; optional properties Void Records membership and queues $groupidentify.
Anectico.capture(event, properties:) event name; properties Void Queues a diagnostic event with current person/session/groups.
Anectico.screen(name, properties:) screen name; properties Void Queues $screen with $screen_name.
Anectico.reset() — Void Logout: creates a new anonymous ID, clears groups, rotates the session, and clears global error-user context and breadcrumbs.
Anectico.distinctId property String? Current known/anonymous ID, or nil before configuration.
Anectico.sessionId property String? Current durable session ID without extending its idle window.

Errors, messages, users, and breadcrumbs

Method Parameters Returns Behavior
Anectico.captureError(error, options:) Swift Error; optional CaptureOptions String Captures a caught error and returns its ID, or "" before configuration.
Anectico.captureError(exception, options:) NSException; optional options String Captures an Objective-C exception without changing app behavior.
Anectico.captureMessage(message, level:options:) message; level default info; options String Captures a diagnostic message and returns its ID.
Anectico.addBreadcrumb(category:message:level:data:) strings; level default info; data Void Adds trail context attached to a later error.
Anectico.setUser(user) AnecticoUser Void Sets global error user context. Cross-signal identity still comes from identify.
Anectico.clearUser() — Void Clears global error user context.
Anectico.captureRawError(...) type, message, frame JSON, fatal, mechanism, tags String Bridge API for React Native/Flutter pre-parsed stacks. Native Swift apps should use captureError.

CaptureOptions fields are tags: [String:String], extra: [String:Any], optional user, optional level, and optional fingerprint: [String]. Fingerprint components are comma-joined; do not put commas inside components. AnecticoUser supports id, email, username, ipAddress, and segment.

Fatal native crashes are persisted and delivered on the next application launch. Keep the exact archive dSYM and upload the bundle or its DWARF binary with anectico symbols upload-dsym MyApp.dSYM. Anectico matches organization-scoped dSYM slices by exact Mach-O image UUID; release and distribution are not dSYM lookup keys.

For native symbolication, each frame carries its image UUID and load address. The complete loaded image set stays in the private crash sidecar; only a bounded table of frame-referenced images rides the recovered occurrence, so large simulator processes cannot exceed the ingest attribute cap.

Every iOS error occurrence automatically carries severity, handled state, an honest capture mechanism, release/distribution, SDK/platform, hardware model code/family, OS version, and app version/build. Caught Swift and explicitly captured Objective-C errors are handled and nonfatal; uncaught Objective-C exceptions and signals are unhandled and fatal. Signal crashes use the crash-time snapshot after relaunch.

These SDK-owned fields take precedence over colliding CaptureOptions.tags. The SDK records a model code such as iPhone15,4, not a unique phone: it never collects IDFV, the user-assigned device name, a serial number, or an installation ID.

The SDK-owned $app_opened lifecycle event carries the same privacy-safe release, app/build, platform, OS, and device-family context. It is emitted once per real foreground transition, while duplicate notifications in one active period are ignored. Backgrounding emits one $app_backgrounded, pauses recurring flushes, and performs one explicit flush; foregrounding recreates exactly one timer without rotating the session by itself. Anectico uses its versioned lifecycle marker to count canonical-person release adoption and the adopted-person error-free rate; host properties cannot override the marker context.

The reserved $release/$app_version string properties are stamped on every captured event (not only $app_opened), sourced from the same release/serviceVersion configure() resolved. Neither is invented: an app that never sets release and has no bundle version to fall back to sends events with neither property. See Reserved event properties.

Agent runs

Anectico.startAgentRun(_ agent: String, options: AgentRunOptions = AgentRunOptions()) -> AgentRun starts a local run handle. It snapshots the start time, identity, and session.

let run = Anectico.startAgentRun(
    "checkout-helper",
    options: AgentRunOptions(agentId: "checkout", agentVersion: "1.4.0", conversationId: "chat-42")
)
// Perform the agent's work, then declare its actual outcome.
let accepted = run.end(.completed)
// On failure instead: run.end(.failed, terminalReason: "tool_failed")

agentId, agentVersion, and conversationId are optional strings mapping to gen_ai.agent.id, gen_ai.agent.version, and gen_ai.conversation.id. The agent name maps to gen_ai.agent.name. Configure and identify the customer before starting a run. A terminal record is an invoke_agent span sent with ingest:write; it does not require an agent-read or agent-write management scope. It is not automatic instrumentation of nested model/tool calls.

end(_ status: AgentRunTerminalStatus = .completed, terminalReason: String? = nil) -> Bool accepts .completed, .failed, .timedOut, .cancelled, or .maxSteps. The multiword wire values are timed_out and max_steps.

Use a stable, non-sensitive reason code, not an exception message, prompt, or customer value. Reasons are trimmed, lowercased, and must match ^[a-z][a-z0-9_]{0,63}$. Omitted reasons default to timeout for a timeout, user_cancelled for cancellation, and the wire status for other outcomes. These are source-declared outcomes; Anectico does not infer success from the absence of an error.

An invalid reason returns false and leaves the handle open. The first accepted outcome wins; later valid calls return true without emitting another span. Acceptance is a local handoff, not confirmation of network delivery. The event-queue flush result does not certify this separate span transport.

recordAgentRun(agent:options:status:terminalReason:startTimeUnixNano:) is the native bridge entry point used by React Native and Flutter. Swift application code should use the typed startAgentRun handle.

Backend propagation

API Parameters Returns Behavior
Anectico.propagationHeaders() — [String:String] Creates a fresh traceparent and identity baggage when configured.
AnecticoPropagation.apply(to:&request) inout URLRequest Void Applies propagation while preserving unrelated baggage.
AnecticoPropagation.newTraceparent() — String Creates a sampled W3C traceparent.
AnecticoPropagation.baggageWithDistinctId(id, existing:) ID; existing baggage String Replaces the Anectico member and preserves unrelated baggage.
AnecticoPropagation.percentEncode(value) string String Encodes a W3C baggage value.

Apply identity baggage only to application backends you trust. A backend must authenticate the mobile request rather than treating the baggage value itself as proof of identity.