EmbraceIO Client
EmbraceIO Client
The EmbraceIO class is the main entry point for interacting with the Embrace SDK. It provides a simplified and streamlined API for configuring, starting, and interacting with the SDK.
In Embrace 7.x, EmbraceIO is the single public client. The Embrace client and Embrace.Options are no longer part of the public API — see the Embrace Client page for details.
Configuration and Initialization
start(options:)
Configures and starts the Embrace SDK in a single step.
static func start(options: EmbraceIO.Options) throws
Parameters:
options: An instance ofEmbraceIO.Optionsthat configures the SDK.
Throws: An error if the SDK cannot be initialized or started properly.
Important Notes:
- Must be called from the main thread.
- There is no longer a separate
setup(options:)/start()sequence —start(options:)configures and starts the SDK in one call. - Won't do anything if the SDK was already started, or if it was disabled via remote configuration.
shared
Provides access to the singleton instance of the EmbraceIO class.
static let shared: EmbraceIO
Note: Instance APIs are accessed through EmbraceIO.shared after calling start(options:).
Creating Options
EmbraceIO.Options is created using factory methods rather than direct initialization. For full details on every option, see Configuration.
Options.withAppId(_:...)
Creates options for use with an Embrace app ID. This is the configuration you use if sending data to Embrace's backend.
class func withAppId(
_ appId: String,
platform: EmbracePlatform = .default,
endpoints: EmbraceEndpoints? = nil,
captureServices: EmbraceIO.CaptureServicesOptions = .default(),
crashReporter: EmbraceIO.CrashReporter = .embrace,
logLevel: EmbraceLogLevel = .default,
otel: EmbraceIO.OTelOptions? = nil
) -> EmbraceIO.Options
Parameters:
appId: The app ID for your Embrace app.platform: The platform the app runs on. Defaults to.default(iOS).endpoints: CustomEmbraceEndpoints. Defaults to Embrace endpoints for the given app ID.captureServices: Determines which capture services will be installed. See Capture Services.crashReporter: The crash reporter to use:.embrace(default),.crashlytics, or.none.logLevel: Verbosity level for console logs. Defaults to.default.otel: OptionalEmbraceIO.OTelOptionsto configure the OpenTelemetry SDK. See Custom OpenTelemetry Resource.
Options.withLocalConfiguration(_:...)
Creates options without an app ID, using a local configuration instead. In this mode, data is not uploaded to Embrace servers, so you must provide custom exporters via EmbraceIO.OTelOptions.
class func withLocalConfiguration(
_ localConfiguration: EmbraceConfigurable = .default,
platform: EmbracePlatform = .default,
captureServices: EmbraceIO.CaptureServicesOptions = .default(),
crashReporter: EmbraceIO.CrashReporter = .embrace,
logLevel: EmbraceLogLevel = .default,
otel: EmbraceIO.OTelOptions
) -> EmbraceIO.Options
Note: The otel parameter is required when using local configuration, since you need to provide exporters to handle the generated data.
Instance Methods and Properties
Core Functionality
stop()
Stops the Embrace SDK from capturing and generating data.
func stop() throws
Throws: An error if not called from the main thread.
Important Notes:
- The SDK cannot be restarted in a process once stopped.
- All active spans will be automatically ended.
- All capture services and session tracking will be stopped.
state
Returns the current state of the SDK.
var state: EmbraceSDKState { get }
Returns: The current SDK state: .notInitialized, .started, or .stopped.
isSDKEnabled
Returns true if the SDK is started and was not disabled through remote configurations.
var isSDKEnabled: Bool { get }
sdkVersion
Returns the version of the Embrace SDK.
class var sdkVersion: String { get }
Session Management
endUserSession()
Ends the current user session and immediately starts a new one in the same foreground/background state.
func endUserSession()
Note: This replaces the previous startNewSession() / endCurrentSession() pair. It is rate-limited to once every 5 seconds.
currentUserSessionId
Returns the identifier for the current Embrace user session, if any.
var currentUserSessionId: String? { get }
deviceId
Returns the identifier used by Embrace for the current device, if any.
var deviceId: String? { get }
Logging
log(_:severity:timestamp:attachment:attributes:stackTraceBehavior:)
Creates and emits a log for the current session.
func log(
_ message: String,
severity: EmbraceLogSeverity = .info,
timestamp: Date = Date(),
attachment: EmbraceLogAttachment? = nil,
attributes: EmbraceAttributes = [:],
stackTraceBehavior: EmbraceStackTraceBehavior = .default
)
Parameters:
message: Body of the log.severity:EmbraceLogSeverityfor the log (.trace,.debug,.info,.warn,.error,.fatal,.critical). Defaults to.info.timestamp: Timestamp for the log. Defaults to now.attachment: OptionalEmbraceLogAttachmentto attach data or a URL to the log.attributes: OptionalEmbraceAttributes(acceptsString,Int,Double, orBoolvalues) to attach to the log.stackTraceBehavior: Defines if stack trace information should be added to the log.
addBreadcrumb(_:attributes:)
Adds a breadcrumb to the current session.
func addBreadcrumb(_ message: String, attributes: EmbraceAttributes = [:])
Performance Monitoring
createSpan(...)
Creates and starts a span, returning an EmbraceSpan?.
func createSpan(
name: String,
parentSpan: EmbraceSpan? = nil,
type: EmbraceType = .performance,
status: EmbraceSpanStatus = .unset,
startTime: Date = Date(),
endTime: Date? = nil,
events: [EmbraceSpanEvent] = [],
links: [EmbraceSpanLink] = [],
attributes: EmbraceAttributes = [:],
autoTerminationCode: EmbraceSpanErrorCode? = nil
) -> EmbraceSpan?
Parameters:
name: The name of the span.parentSpan: The parentEmbraceSpan, if this span is a child.type: The type of span. Defaults to.performance.status: The initial span status. Defaults to.unset.startTime/endTime: Optional custom start and end times.events: Events to attach to the span.links: Links to other spans.attributes: A dictionary of attributes to set on the span.autoTerminationCode:EmbraceSpanErrorCodeto automatically close the span if the session ends while it is still open.
Returns: An EmbraceSpan, or nil if the span could not be created. This happens when the SDK has not been started yet, or when the per-session span limit has been reached — in which case the span is dropped and a warning is logged. Because of this, always use optional chaining (span?.end()) when working with the result.
addSessionEvent(name:attributes:)
Adds an event to the current session span.
// Add an event by name
func addSessionEvent(name: String, attributes: EmbraceAttributes = [:])
// Add a previously built event
func addSessionEvent(_ event: EmbraceSpanEvent)
User Identification and Metadata
User Properties
Set the user identifier directly on the EmbraceIO.shared instance:
EmbraceIO.shared.userIdentifier = "anon_user_1a2b3c4d"
// Clear the user identifier
EmbraceIO.shared.userIdentifier = nil
Important: The userIdentifier should be an anonymized identifier. Use hashed values, UUIDs, or other privacy-safe identifiers.
Session Properties
// Set a property (pass value: nil to remove)
EmbraceIO.shared.setProperty(
key: "subscription_tier",
value: "premium",
lifespan: .userSession
)
// Remove all properties
EmbraceIO.shared.removeAllProperties(lifespans: [.userSession])
Personas
// Add a persona
EmbraceIO.shared.addPersona("premium_user", lifespan: .userSession)
// Remove a persona
EmbraceIO.shared.removePersona("premium_user", lifespan: .userSession)
// Remove all personas
EmbraceIO.shared.removeAllPersonas(lifespans: [.userSession])
// Get current personas
EmbraceIO.shared.getCurrentPersonas { personas in
print("Current personas: \(personas)")
}
Metadata Lifespans
Properties and personas can have different lifespans:
.userSession- Scoped to the current user session. The metadata is included in every session part of that user session and survives process death for as long as the user session does. Removed when the user session ends..process- Removed when app process ends.permanent- Persists until app is uninstalled
MetadataLifespan.session from 6.x is now MetadataLifespan.userSession. In 6.x the metadata applied to a single foreground or background session; in 7.x it applies to the whole user session.
removeAllProperties(lifespans:) and removeAllPersonas(lifespans:) are not scoped to the active user session or process — passing .userSession removes the metadata of every user session in storage, not just the current one. To clear a single value from the active user session, use setProperty(key:value:lifespan:) with a nil value or removePersona(_:lifespan:).
Custom OpenTelemetry Resource
You can pass a custom OpenTelemetry Resource object when initializing the Embrace SDK. This allows you to attach custom resource attributes to all telemetry data (spans, logs) generated by the SDK. Custom resources take priority over any default resources generated by the Embrace SDK.
Usage
import EmbraceIO
import OpenTelemetrySdk
let customResource = Resource(attributes: [
"service.name": .string("my-ios-app"),
"deployment.environment": .string("production"),
"custom.attribute": .string("my-value")
])
let otelOptions = EmbraceIO.OTelOptions(resource: customResource)
let options = EmbraceIO.Options.withAppId(
"YOUR_APP_ID",
otel: otelOptions
)
try EmbraceIO.start(options: options)
OTelOptions
The EmbraceIO.OTelOptions class provides full control over the OpenTelemetry pipeline:
public init(
resource: Resource? = nil,
spanProcessors: [SpanProcessor] = [],
spanExporters: [SpanExporter] = [],
logProcessors: [LogRecordProcessor] = [],
logExporters: [LogRecordExporter] = [],
registersGlobalProviders: Bool = false
)
Parameters:
resource: CustomResourceto attach to all telemetry data. Takes priority over Embrace-generated resources.spanProcessors: Custom span processors to add to the pipeline.spanExporters: Custom span exporters to receive exported span data.logProcessors: Custom log record processors to add to the pipeline.logExporters: Custom log record exporters to receive exported log data.registersGlobalProviders: Whether to install the Embrace tracer and logger providers as the process-wide OpenTelemetry providers. Defaults tofalse.
OpenTelemetry Providers
These accessors expose the OpenTelemetry providers that back the Embrace pipeline. They all return nil unless the SDK was started with an EmbraceIO.OTelOptions. Signals created through them are captured by Embrace, forwarded to your custom processors and exporters, and count against the same per-session limits as createSpan and log. See OpenTelemetry Providers for the full behavior.
tracerProvider
The TracerProvider backing the Embrace pipeline.
var tracerProvider: TracerProvider? { get }
loggerProvider
The LoggerProvider backing the Embrace pipeline.
var loggerProvider: LoggerProvider? { get }
tracer(instrumentationName:instrumentationVersion:)
Returns a Tracer attached to the Embrace pipeline.
func tracer(
instrumentationName: String,
instrumentationVersion: String? = nil
) -> Tracer?
Parameters:
instrumentationName: Name of the instrumentation library creating the spans. This is the name of your instrumentation, not of the library being instrumented.instrumentationVersion: Version of the instrumentation library, if any.
logger(instrumentationScopeName:instrumentationVersion:)
Returns a Logger attached to the Embrace pipeline.
func logger(
instrumentationScopeName: String,
instrumentationVersion: String? = nil
) -> Logger?
Parameters:
instrumentationScopeName: Name of the instrumentation library emitting the logs. This is the name of your instrumentation, not of the library being instrumented.instrumentationVersion: Version of the instrumentation library, if any.
Usage:
import EmbraceIO
import OpenTelemetryApi
let span = EmbraceIO.shared
.tracer(instrumentationName: "com.mycompany.checkout")?
.spanBuilder(spanName: "checkout")
.startSpan()
span?.end()
Code Examples
Basic Setup and Start
import EmbraceIO
import SwiftUI
struct MyApp: App {
init() {
do {
try EmbraceIO.start(options: EmbraceIO.Options.withAppId("YOUR_APP_ID"))
} catch {
print("Error starting Embrace: \(error.localizedDescription)")
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Setup with Custom Resource and Capture Services
import EmbraceIO
import OpenTelemetrySdk
let resource = Resource(attributes: [
"deployment.environment": .string("staging")
])
let options = EmbraceIO.Options.withAppId(
"YOUR_APP_ID",
captureServices: .default(),
logLevel: .debug,
otel: EmbraceIO.OTelOptions(resource: resource)
)
try EmbraceIO.start(options: options)
Logging and Spans
// Basic logging
EmbraceIO.shared.log("User logged in", severity: .info)
// Logging with attributes
EmbraceIO.shared.log(
"Network request failed",
severity: .error,
attributes: ["url": "https://api.example.com"]
)
// Creating a span
let span = EmbraceIO.shared.createSpan(
name: "data-loading",
type: .performance,
attributes: ["source": "network"]
)
// Do work...
span?.end()
Session and User Management
// Set user info
EmbraceIO.shared.userIdentifier = "anon_user_7f8e9a1b"
// Add session properties
EmbraceIO.shared.setProperty(
key: "screen",
value: "home",
lifespan: .userSession
)
// Check SDK state
if EmbraceIO.shared.state == .started {
print("Session: \(EmbraceIO.shared.currentUserSessionId ?? "none")")
}
// End the current user session and start a new one
EmbraceIO.shared.endUserSession()
GitHub Source: EmbraceIO