From 0f1353cd1f4bbc12a88902d330c048955e54915d Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Wed, 10 Jun 2026 10:28:32 +0200 Subject: [PATCH] feat(apple): add sample code for SentryObjC --- .../apple/common/configuration/app-hangs.mdx | 61 ++++- .../graphql-operation-tracking.mdx | 9 + .../configuration/http-client-errors.mdx | 55 ++++- .../apple/common/configuration/metric-kit.mdx | 20 +- .../apple/common/configuration/options.mdx | 105 +++++++- .../common/configuration/out-of-memory.mdx | 10 +- .../apple/common/configuration/swizzling.mdx | 20 +- .../configuration/watchdog-terminations.mdx | 12 +- .../enriching-events/viewhierarchy/index.mdx | 7 + .../apple/common/integrations/default.mdx | 10 + .../apple/common/profiling/index.mdx | 57 +++++ .../automatic-instrumentation.mdx | 226 +++++++++++++++++- .../tracing/trace-propagation/index.mdx | 12 + .../apple/common/troubleshooting/index.mdx | 44 ++-- .../common/usage/in-app-frames/index.mdx | 12 +- .../apple/guides/ios/manual-setup.mdx | 20 +- platform-includes/capture-error/apple.mdx | 33 ++- platform-includes/capture-message/apple.mdx | 6 + .../auto-session-tracking/apple.mdx | 21 +- .../before-send-fingerprint/apple.mdx | 14 ++ .../configuration/before-send-span/apple.mdx | 16 ++ .../configuration/before-send/apple.mdx | 12 + .../configuration/config-intro/apple.mdx | 14 ++ .../configuration/sample-rate/apple.mdx | 8 + .../attach-screenshots/apple.mdx | 21 +- .../attach-viewhierarchy/apple.mdx | 21 +- .../attachment-init-with-bytes/apple.mdx | 7 + .../attachment-init-with-path/apple.mdx | 7 + .../attachment-max-size/apple.mdx | 8 + .../attachment-upload/apple.mdx | 22 ++ .../breadcrumbs/before-breadcrumb/apple.mdx | 10 + .../breadcrumbs/breadcrumbs-example/apple.mdx | 10 + .../scopes/configure-scope/apple.mdx | 11 + .../scopes/scope-callback-param/apple.mdx | 13 + .../enriching-events/set-context/apple.mdx | 12 + .../enriching-events/set-tag/apple.mdx | 8 + .../enriching-events/set-user/apple.mdx | 9 + .../enriching-events/unset-user/apple.mdx | 6 + .../getting-started-config/apple.mdx | 22 +- platform-includes/logs/options/apple.mdx | 33 +++ platform-includes/logs/setup/apple.mdx | 18 ++ platform-includes/logs/usage/apple.mdx | 28 +++ platform-includes/metrics/options/apple.mdx | 10 + platform-includes/pass-scope/apple.mdx | 13 + .../performance/add-spans-example/apple.mdx | 32 +++ .../apple.mdx | 11 + .../configure-sample-rate/apple.mdx | 22 ++ .../connect-errors-spans/apple.mdx | 14 ++ .../apple.mdx | 26 ++ .../custom-performance-metrics/apple.mdx | 16 ++ .../custom-sampling-context/apple.mdx | 20 ++ .../enable-manual-instrumentation/apple.mdx | 18 ++ .../force-sampling-decision/apple.mdx | 11 + .../performance/improving-data/apple.mdx | 26 ++ .../retrieve-transaction/apple.mdx | 12 + .../performance/traces-sample-rate/apple.mdx | 8 + .../traces-sampler-as-filter/apple.mdx | 17 ++ .../traces-sampler-as-sampler/apple.mdx | 34 +++ platform-includes/scope-callback/apple.mdx | 16 ++ .../sensitive-data/set-tag/apple.mdx | 8 + .../sensitive-data/set-user/apple.mdx | 14 ++ platform-includes/set-environment/apple.mdx | 9 + platform-includes/set-extra/apple.mdx | 8 + .../set-fingerprint/basic/apple.mdx | 11 + .../database-connection/apple.mdx | 14 ++ .../set-fingerprint/rpc/apple.mdx | 20 ++ platform-includes/set-level/apple.mdx | 8 + platform-includes/set-release/apple.mdx | 8 + .../user-feedback/sdk-api-example/apple.mdx | 26 +- 69 files changed, 1459 insertions(+), 43 deletions(-) diff --git a/docs/platforms/apple/common/configuration/app-hangs.mdx b/docs/platforms/apple/common/configuration/app-hangs.mdx index 1a4febbe5e051..312703051eeaa 100644 --- a/docs/platforms/apple/common/configuration/app-hangs.mdx +++ b/docs/platforms/apple/common/configuration/app-hangs.mdx @@ -31,7 +31,6 @@ Because the app hang detection integration uses SentryCrashIntegration to captur You can filter and modify app hang events in `beforeSend` by checking the event exception type: - ```swift {tabTitle:Swift} import Sentry @@ -60,8 +59,21 @@ SentrySDK.start { options in }]; ``` -Starting with version 8.0.0, this feature has been enabled by default. To disable it: +```objc {tabTitle:Objective-C (SentryObjC)} +#import +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + if (event.exceptions.count == 1 && [event.exceptions.firstObject.type isEqualToString:@"App Hanging"]) { + // modify event here or return nil to discard the event + } + return event; + } +}]; +``` + +Starting with version 8.0.0, this feature has been enabled by default. To disable it: ```swift {tabTitle:Swift} import Sentry @@ -79,12 +91,19 @@ SentrySDK.start { options in options.dsn = @"___PUBLIC_DSN___"; options.enableAppHangTracking = NO; }]; +``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableAppHangTracking = NO; +}]; ``` You can change the timeout by changing the `appHangTimeoutInterval` option: - ```swift {tabTitle:Swift} import Sentry @@ -101,7 +120,15 @@ SentrySDK.start { options in options.dsn = @"___PUBLIC_DSN___"; options.appHangTimeoutInterval = 1; }]; +``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.appHangTimeoutInterval = 1; +}]; ``` ### Pause and Resume App Hang Tracking @@ -129,7 +156,17 @@ SentrySDK.resumeAppHangTracking() // and you don't want the Cocoa SDK to report it. [SentrySDK resumeAppHangTracking]; +``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK pauseAppHangTracking]; +// Do something that might cause the app to hang, +// and you don't want the Cocoa SDK to report it. + +[SentryObjCSDK resumeAppHangTracking]; ``` ### App Hangs V2 @@ -160,6 +197,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableAppHangTrackingV2 = YES; // Only available in 8.50.0–8.x +}]; +``` + #### Fatal App Hangs Starting with version 8.50.0, the SDK automatically detects and reports fatal app hangs. If the user or the [system watchdog](https://developer.apple.com/documentation/xcode/addressing-watchdog-terminations) terminates your app during an app hang, the SDK reports it as a fatal app hang on the next startup. @@ -188,6 +234,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableReportNonFullyBlockingAppHangs = NO; +}]; +``` + ## App Hang Rate diff --git a/docs/platforms/apple/common/configuration/graphql-operation-tracking.mdx b/docs/platforms/apple/common/configuration/graphql-operation-tracking.mdx index 268906645ce65..424514a38a14f 100644 --- a/docs/platforms/apple/common/configuration/graphql-operation-tracking.mdx +++ b/docs/platforms/apple/common/configuration/graphql-operation-tracking.mdx @@ -29,6 +29,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableGraphQLOperationTracking = YES; +}]; +``` + ## How It Works The SDK automatically detects GraphQL requests by checking: diff --git a/docs/platforms/apple/common/configuration/http-client-errors.mdx b/docs/platforms/apple/common/configuration/http-client-errors.mdx index be6016c330083..6affcb09bfff3 100644 --- a/docs/platforms/apple/common/configuration/http-client-errors.mdx +++ b/docs/platforms/apple/common/configuration/http-client-errors.mdx @@ -6,10 +6,8 @@ description: "This feature, once enabled, automatically captures HTTP client err Once enabled, this feature automatically captures HTTP client errors, like bad response codes, as error events and reports them to Sentry. The error event will contain the `request` and `response` data, such as `url`, `status_code`, and so on. Depending on your HTTP request setup, it can happen that the stacktrace of these events doesn't pinpoint the exact location of the HTTP request in your code. If that's the case, you can look at the HTTP request info of the issue, which contains things like URL and HTTP headers. - Since 8.0.0, this feature has been enabled by default. To disable it: - ```swift {tabTitle:Swift} import Sentry @@ -28,8 +26,16 @@ SentrySDK.start { options in }]; ``` -By default, only HTTP client errors with a response code between `500` and `599` are captured as error events, but you can change this behavior by setting the `failedRequestStatusCodes` option: +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableCaptureFailedRequests = NO; +}]; +``` +By default, only HTTP client errors with a response code between `500` and `599` are captured as error events, but you can change this behavior by setting the `failedRequestStatusCodes` option: ```swift {tabTitle:Swift} import Sentry @@ -52,8 +58,18 @@ SentrySDK.start { options in }]; ``` -HTTP client errors from every target (`.*` regular expression) are automatically captured, but you can change this behavior by setting the `failedRequestTargets` option with either a regular expression or a plain `String`. A plain string must contain at least one of the items from the list. Plain strings don't have to be full matches, meaning the URL of a request is matched when it contains a string provided through the option: +```objc {tabTitle:Objective-C (SentryObjC)} +#import +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + SentryObjCHttpStatusCodeRange *httpStatusCodeRange = + [[SentryObjCHttpStatusCodeRange alloc] initWithMin:400 max:599]; + options.failedRequestStatusCodes = @[ httpStatusCodeRange ]; +}]; +``` + +HTTP client errors from every target (`.*` regular expression) are automatically captured, but you can change this behavior by setting the `failedRequestTargets` option with either a regular expression or a plain `String`. A plain string must contain at least one of the items from the list. Plain strings don't have to be full matches, meaning the URL of a request is matched when it contains a string provided through the option: ```swift {tabTitle:Swift} import Sentry @@ -73,6 +89,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.failedRequestTargets = @[ @"www.example.com" ]; +}]; +``` + ### GraphQL Operation Tracking When the `enableGraphQLOperationTracking` option is enabled (disabled by default), the SDK extracts the GraphQL operation name from HTTP requests that have `Content-Type: application/json` and contain a JSON body with an `operationName` field. The operation name is then included in the error event's context as `graphql.operation_name`, making it easier to identify which GraphQL operation failed. Learn more in the GraphQL Operation Tracking documentation. @@ -95,6 +120,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableGraphQLOperationTracking = YES; +}]; +``` + When enabled, GraphQL operation names are also added to HTTP breadcrumbs as `graphql_operation_name` (when network breadcrumbs are enabled). Error events may contain PII data, such as `Headers` and `Cookies`. Sentry already does data scrubbing by default, but you can scrub any data before it is sent. Learn more in [Scrubbing Sensitive Data](/platforms/apple/guides/ios/data-management/sensitive-data/). @@ -105,7 +139,6 @@ These events are searchable and you can set alerts on them if you use the `http. The captured error event can be customized or dropped with a `beforeSend`: - ```swift {tabTitle:Swift} import Sentry @@ -129,3 +162,15 @@ SentrySDK.start { options in } }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + // modify event here or return nil to discard the event + return event; + } +}]; +``` diff --git a/docs/platforms/apple/common/configuration/metric-kit.mdx b/docs/platforms/apple/common/configuration/metric-kit.mdx index 2fd5973997c22..d2652c8c99df2 100644 --- a/docs/platforms/apple/common/configuration/metric-kit.mdx +++ b/docs/platforms/apple/common/configuration/metric-kit.mdx @@ -15,7 +15,6 @@ You can identify MetricKit events by looking at the `mx_hang_diagnostic`, `mx_cp Enable this feature by setting the `enableMetricKit` option to `true`: - ```swift {tabTitle:Swift} import Sentry @@ -34,6 +33,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableMetricKit = YES; +}]; +``` + You can enable `enableMetricKitRawPayload` to view the raw MetricKit diagnostic payload in JSON format as an attachment on the converted event in Sentry. This feature is available on Cocoa 8.29.0 and up. ```swift {tabTitle:Swift} @@ -55,3 +63,13 @@ SentrySDK.start { options in options.enableMetricKitRawPayload = YES; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableMetricKit = YES; + options.enableMetricKitRawPayload = YES; +}]; +``` diff --git a/docs/platforms/apple/common/configuration/options.mdx b/docs/platforms/apple/common/configuration/options.mdx index 97269394e60d4..9be8f184bf0df 100644 --- a/docs/platforms/apple/common/configuration/options.mdx +++ b/docs/platforms/apple/common/configuration/options.mdx @@ -190,6 +190,13 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + [options addInAppInclude:@"MyFramework"]; +}]; +``` + @@ -228,6 +235,18 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.initialScope = ^(SentryObjCScope *scope) { + [scope setTagValue:@"my value" forKey:@"my-tag"]; + return scope; + }; +}]; +``` + @@ -431,6 +450,21 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeSendSpan = ^SentryObjCSpan * _Nullable(SentryObjCSpan * _Nonnull span) { + // Filter out spans with certain operations + if ([span.operation isEqualToString:@"db.query"]) { + return nil; + } + return span; + }; +}]; +``` + @@ -469,6 +503,22 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableLogs = YES; + options.beforeSendLog = ^SentryObjCLog * _Nullable(SentryObjCLog * _Nonnull log) { + // Filter out info level logs + if (log.level == SentryObjCLogLevelInfo) { + return nil; + } + return log; + }; +}]; +``` + Learn more about log filtering in the logs documentation. @@ -503,6 +553,19 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.attachScreenshot = YES; + options.beforeCaptureScreenshot = ^BOOL(SentryObjCEvent * _Nonnull event) { + // Prevent screenshots in certain views + return !isSensitiveView(); + }; +}]; +``` + @@ -535,6 +598,19 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.attachViewHierarchy = YES; + options.beforeCaptureViewHierarchy = ^BOOL(SentryObjCEvent * _Nonnull event) { + // Prevent view hierarchy capture in certain views + return !isSensitiveView(); + }; +}]; +``` + @@ -567,6 +643,18 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.onCrashedLastRun = ^(SentryObjCEvent * _Nonnull event) { + // Perform actions when a crash was detected on last run + NSLog(@"App crashed on last run"); + }; +}]; +``` + @@ -611,6 +699,21 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.onLastRunStatusDetermined = ^(SentryObjCLastRunStatus status, SentryObjCEvent * _Nullable crashEvent) { + if (status == SentryObjCLastRunStatusDidCrash) { + NSLog(@"App crashed on last run: %@", crashEvent); + } else { + NSLog(@"App did not crash on last run"); + } + }; +}]; +``` + ## Tracing Options @@ -1196,14 +1299,12 @@ When enabled, the SDK captures fatal C++ exceptions using a more reliable mechan **Note:** The mechanism of hooking into `__cxa_throw` could cause issues with symbolication on iOS due to caching of symbol references. - When enabled, the SDK uses a more efficient mechanism for detecting watchdog terminations. - diff --git a/docs/platforms/apple/common/configuration/out-of-memory.mdx b/docs/platforms/apple/common/configuration/out-of-memory.mdx index d4345ef938616..79336f2275a45 100644 --- a/docs/platforms/apple/common/configuration/out-of-memory.mdx +++ b/docs/platforms/apple/common/configuration/out-of-memory.mdx @@ -8,7 +8,6 @@ We renamed this integration to + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableSwizzling = NO; +}]; +``` ## Deactivate Swizzling for Specific Classes @@ -56,7 +64,6 @@ To deactivate swizzling for specific classes, you can use the option `swizzleCla - `YourApp.MyUIViewControllerA` - `MyApp.MyUIViewController` - ```swift {tabTitle:Swift} import Sentry @@ -77,3 +84,14 @@ SentrySDK.start { options in ]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.swizzleClassNameExcludes = [NSSet setWithObjects: + @"MyUIViewController", + nil + ]; +}]; +``` diff --git a/docs/platforms/apple/common/configuration/watchdog-terminations.mdx b/docs/platforms/apple/common/configuration/watchdog-terminations.mdx index 72b44ac237bec..268653d78dfe1 100644 --- a/docs/platforms/apple/common/configuration/watchdog-terminations.mdx +++ b/docs/platforms/apple/common/configuration/watchdog-terminations.mdx @@ -40,7 +40,6 @@ If you're interested in the implementation details, you can check out [the code] If you'd like to opt out of this feature, you can do so using the `enableWatchdogTerminationTracking` option: - ```swift {tabTitle:Swift} import Sentry @@ -59,6 +58,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableWatchdogTerminationTracking = NO; +}]; +``` + If you disable the `enableCrashHandler` option, the SDK will disable watchdog termination tracking. This will prevent false positive watchdog termination reporting for every crash. #### FAQ @@ -69,7 +77,7 @@ Yes. If the watchdog ends your app due to excessive memory usage, the Apple SDK **Do watchdog terminations include force terminations from the user?** -No, watchdog terminations don't include force terminations from the user, because when the user force kills your app, your app goes through the normal termination process, via the [applicationWillTerminate](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/applicationwillterminate(_:)) delegate method that the Apple SDK also subscribes to. If the user force kills your app while it's hanging, the SDK will report this as a fatal app hang if you have enabled App Hangs V2. +No, watchdog terminations don't include force terminations from the user, because when the user force kills your app, your app goes through the normal termination process, via the [applicationWillTerminate]() delegate method that the Apple SDK also subscribes to. If the user force kills your app while it's hanging, the SDK will report this as a fatal app hang if you have enabled App Hangs V2. **Do watchdog terminations include fatal app hangs?** diff --git a/docs/platforms/apple/common/enriching-events/viewhierarchy/index.mdx b/docs/platforms/apple/common/enriching-events/viewhierarchy/index.mdx index c477ded2b9c36..c8580511edb3e 100644 --- a/docs/platforms/apple/common/enriching-events/viewhierarchy/index.mdx +++ b/docs/platforms/apple/common/enriching-events/viewhierarchy/index.mdx @@ -52,6 +52,13 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.attachViewHierarchy = YES; + options.reportAccessibilityIdentifier = NO; +}]; +``` ## Viewing View Hierarchy Attachments diff --git a/docs/platforms/apple/common/integrations/default.mdx b/docs/platforms/apple/common/integrations/default.mdx index 516ae32bc8068..c2e25c458f70f 100644 --- a/docs/platforms/apple/common/integrations/default.mdx +++ b/docs/platforms/apple/common/integrations/default.mdx @@ -60,3 +60,13 @@ NSMutableArray *integrations = [SentryOptions defaultIntegrations].mutableCopy; options.integrations = integrations; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +NSMutableArray *integrations = [SentryObjCOptions defaultIntegrations].mutableCopy; +[integrations removeObject:@"SentryAutoBreadcrumbTrackingIntegration"]; +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.integrations = integrations; +}]; +``` diff --git a/docs/platforms/apple/common/profiling/index.mdx b/docs/platforms/apple/common/profiling/index.mdx index 3c73548cb963e..26119071a5847 100644 --- a/docs/platforms/apple/common/profiling/index.mdx +++ b/docs/platforms/apple/common/profiling/index.mdx @@ -49,6 +49,17 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.configureProfiling = ^(SentryObjCProfileOptions *profiling) { + profiling.sessionSampleRate = 1.f; + }; +}]; +``` + By default, `sessionSampleRate` is `0`, so you'll need to set it to a higher value to receive profile data. The SDK evaluates `sessionSampleRate` once per Sentry user session, and foregrounding the app only reevaluates it if a new session starts. See user session documentation for more information on user sessions. See the subsections below to learn about the various ways the profiler can be started and stopped. @@ -115,6 +126,19 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.tracesSampleRate = @1.f; + options.configureProfiling = ^(SentryObjCProfileOptions *profiling) { + profiling.sessionSampleRate = 1.f; + profiling.lifecycle = SentryObjCProfileLifecycleTrace; + }; +}]; +``` + The `sessionSampleRate` for profiles is _relative_ to the `tracesSampleRate`: if `tracesSampleRate` and `sessionSampleRate` are both `0.5`, then on average 25% of attempts to start the profiler will result in actual data collection. @@ -151,6 +175,18 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.configureProfiling = ^(SentryObjCProfileOptions *profiling) { + profiling.sessionSampleRate = 1.f; + profiling.profileAppStarts = YES; + }; +}]; +``` + If configured with manual lifecycle, a profile starts on the next app launch, and continues until you call `SentrySDK.stopProfiler()`. If configured with trace lifecycle, app start profiles are attached to a special performance transaction operation called `app.launch` and displayed in the product as `launch`. It is stopped either when the SDK is started, or, if Time to Initial Display (TTID)/Time to Full Display (TTFD) tracking is enabled, when the SDK determines that TTID/TTFD has been reached. @@ -199,6 +235,16 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.tracesSampleRate = @1.0; // tracing must be enabled for profiling + options.profilesSampleRate = @1.0; // see also `profilesSampler` if you need custom sampling logic +}]; +``` + ## Launch Profiling (removed in 9.0.0) @@ -237,6 +283,17 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.tracesSampleRate = @1.0; // tracing must be enabled for profiling + options.profilesSampleRate = @1.0; // see also `profilesSampler` if you need custom sampling logic + options.enableAppLaunchProfiling = YES; +}]; +``` + ## Continuous Profiling Beta (removed in 9.0.0) diff --git a/docs/platforms/apple/common/tracing/instrumentation/automatic-instrumentation.mdx b/docs/platforms/apple/common/tracing/instrumentation/automatic-instrumentation.mdx index a9b4d9e1dc487..15144fd3792ac 100644 --- a/docs/platforms/apple/common/tracing/instrumentation/automatic-instrumentation.mdx +++ b/docs/platforms/apple/common/tracing/instrumentation/automatic-instrumentation.mdx @@ -50,6 +50,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + [options addInAppInclude:@"MyFramework"]; +}]; +``` + This is particularly useful for modularized applications or apps using third-party UI frameworks where you want to track performance metrics for view controllers in those frameworks. The SDK creates spans to provide insight into the time consumed by each of the methods shown in the screenshot below. Due to implementation limitations, the SDK only adds a span for loadView if the instrumented view controller implements it. The SDK adds spans for all other methods, whether you implement them in your view controller or not. @@ -91,6 +100,19 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableUIViewControllerTracing = NO; + + + // Before 8.0.0 + options.enableUIViewControllerTracking = NO; +}]; +``` + You can deactivate tracing for specific UIViewControllers by configuring `swizzleClassNameExcludes`: ```swift {tabTitle:Swift} @@ -114,6 +136,17 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.swizzleClassNameExcludes = [NSSet setWithObjects: + @"MyUIViewController", + nil + ]; +}]; +``` + [UIViewController]: https://developer.apple.com/documentation/uikit/uiviewcontroller ## App Start Tracing @@ -144,6 +177,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableAutoPerformanceTracing = NO; +}]; +``` + The SDK differentiates between a cold and a warm start, but doesn't track hot starts/resumes. - **Cold start**: App launched for the first time, after a reboot or update. A cold start begins when the process is created. @@ -203,6 +245,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enablePreWarmedAppStartTracing = NO; +}]; +``` + ### Standalone App Start Tracing @@ -235,6 +286,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.experimental.enableStandaloneAppStartTracing = YES; +}]; +``` + Since standalone app start transactions use the `app.start` operation, you can use a custom `tracesSampler` to set a dedicated sample rate for app starts without increasing your overall sample rate: ```swift {tabTitle:Swift} @@ -267,6 +327,21 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.experimental.enableStandaloneAppStartTracing = YES; + options.tracesSampler = ^NSNumber * _Nullable(SentryObjCSamplingContext * context) { + if ([context.transactionContext.operation isEqualToString:@"app.start"]) { + return @1.0; + } + return @0.1; + }; +}]; +``` + #### Extending the App Launch @@ -345,6 +420,35 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +@interface AppDelegate () +@property (nonatomic, strong) id appStartSpan; +@end + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.experimental.enableStandaloneAppStartTracing = YES; + }]; + self.appStartSpan = [SentryObjCSDK extendAppLaunch]; + + id configSpan = [self.appStartSpan startChildWithOperation:@"app.init" + description:@"fetch remote config"]; + [self fetchRemoteConfig]; + [configSpan finish]; + + return YES; +} + +// Later, when your app is fully ready: +- (void)onDataLoaded { + [self.appStartSpan finish]; +} +``` + You can also call `SentrySDK.finishExtendedAppLaunch()` instead of `finish()` on the span — both are equivalent. **SwiftUI:** @@ -355,7 +459,7 @@ import Sentry @main struct MyApp: App { var appStartSpan: (any Span)? - + init() { SentrySDK.start { options in options.dsn = "___PUBLIC_DSN___" @@ -429,6 +533,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableNetworkTracking = NO; +}]; +``` + [NSURLSession]: https://developer.apple.com/documentation/foundation/nsurlsession [NSURLConnection]: https://developer.apple.com/documentation/foundation/nsurlconnection @@ -457,6 +570,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.tracePropagationTargets = @[@"MyAppDomain.com"] +}]; +``` + The option may contain a list of `NSString` or `NSRegularExpression` against which the URLs of outgoing requests are matched. If one of the entries in the list matches the URL of an outgoing request, trace data will be attached to that request. String entries do not have to be full matches, meaning the URL of a request is matched when it contains a string provided through the option. If `tracePropagationTargets` is not provided, trace data is attached to every outgoing request from the instrumented client. @@ -491,6 +613,18 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableFileIOTracing = NO; + + // Before 8.0.0 + options.enableFileIOTracking = NO; +}]; +``` + Starting with iOS 18, macOS 15, and tvOS 18, the `NSFileManager` is no longer backed by `NSData` and needs to be swizzled directly. This feature is currently experimental and disabled by default. To use automatic file I/O tracing for `NSFileManager` you need to enable it: @@ -515,6 +649,16 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableFileIOTracing = YES; + options.enableFileManagerSwizzling = YES; +}]; +``` + Before 9.0.0, this option was experimental: ```swift {tabTitle:Swift} @@ -537,6 +681,16 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableFileIOTracing = YES; + options.experimental.enableFileManagerSwizzling = YES; +}]; +``` + Starting with iOS 18, tvOS 18, and macOS 15 the Swift classes `Data` and `FileManager` are no longer backed by their Objective-C counterparts `NSData` and `NSFileManager` and therefore cannot be instrumented automatically anymore. Instead, please use [Manual File I/O Tracing](#manual-fileio-tracing). [NSData]: https://developer.apple.com/documentation/foundation/nsdata @@ -645,6 +799,17 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableFileIOTracing = YES; + options.enableDataSwizzling = NO; + options.enableFileManagerSwizzling = NO; +}]; +``` + Before 9.0.0, these options were experimental: ```swift {tabTitle:Swift} @@ -694,6 +859,18 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableCoreDataTracing = NO; + + // Before 8.0.0 + options.enableCoreDataTracking = NO +}]; +``` + ## User Interaction Tracing User interaction tracing, once enabled, captures transactions for clicks. This feature is unavailable for SwiftUI. Since 8.0.0, this feature has been enabled by default. To disable it: @@ -716,6 +893,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableUserInteractionTracing = NO; +}]; +``` + The SDK composes the transaction name out of the host `UIViewController` and the method that the `UIView` is calling; for example, `YourApp_LoginUIViewController.loginButton`. The SDK sets the transaction operation to `ui.action`. If the SDK detects the interaction's origin was a click, it adds `click` as a suffix to the operation. The transaction finishes automatically after it reaches the specified [idleTimeout](/platforms/apple/guides/ios/configuration/options/#idleTimeout) and all of its child spans are finished. The `idleTimeout` defaults to `3.0` seconds. @@ -748,6 +934,17 @@ func loadUserDataOnClick() { } ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +- (void)loadUserDataOnClick { + id span = SentryObjCSDK.span; + id innerSpan = [span startChildWithOperation:@"loadUserData"]; + // omitted code + [innerSpan finish]; +} +``` + When the user interaction transaction is not finished yet, but the user makes a new interaction, or the SDK starts a new UIViewController transaction, the SDK automatically finishes the previous user interaction transaction. This is because only one transaction can be bound to the scope at a time. However, if the same view has been interacted with (for example, a `UIButton` was clicked again within the `idleTimeout` window), the idle timer will be reset and the transaction duration will be extended with the `idleTimeout` value. ## Time to Initial Display @@ -798,6 +995,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableTimeToFullDisplayTracing = YES; +}]; +``` + We can't detect when your UIViewController is fully loaded. Only you, the user, can achieve this. Therefore, you have to manually call the API to get proper statistics. _You can achieve this by using the following code:_ @@ -813,6 +1019,12 @@ SentrySDK.reportFullyDisplayed() [SentrySDK reportFullyDisplayed]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK reportFullyDisplayed]; +``` + If the span finishes through the API, its `status` is set to `SpanStatus.OK`. If the span doesn't finish after 30 seconds, it will be finished by the SDK automatically, and its `status` will be set to `SpanStatus.DEADLINE_EXCEEDED`, also its duration will match the same of the `Time to initial display` span and the description will contain `Deadline Exceeded` suffix. If a call to `reportFullyDisplayed()` happens before the view controller appears, the reported time will be shifted to `Time to initial display` measured time. @@ -852,5 +1064,17 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableAutoPerformanceTracing = NO; + + // Before 8.0.0 + options.enableAutoPerformanceTracking = NO; +}]; +``` + [UIWindow]: https://developer.apple.com/documentation/uikit/uiwindowdidbecomevisiblenotification [didFinishLaunching]: https://developer.apple.com/documentation/uikit/uiapplication/1622971-didfinishlaunchingnotification diff --git a/docs/platforms/apple/common/tracing/trace-propagation/index.mdx b/docs/platforms/apple/common/tracing/trace-propagation/index.mdx index b913ece23d8ba..9f07f541e5c3a 100644 --- a/docs/platforms/apple/common/tracing/trace-propagation/index.mdx +++ b/docs/platforms/apple/common/tracing/trace-propagation/index.mdx @@ -77,3 +77,15 @@ SentrySDK.start { options in ]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.tracePropagationTargets = @[ + @"https://myproject.org", + @"https://api.otherservice.org/" + ]; +}]; +``` diff --git a/docs/platforms/apple/common/troubleshooting/index.mdx b/docs/platforms/apple/common/troubleshooting/index.mdx index 3adff0279e008..3293381464b82 100644 --- a/docs/platforms/apple/common/troubleshooting/index.mdx +++ b/docs/platforms/apple/common/troubleshooting/index.mdx @@ -99,6 +99,12 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.swizzleClassNameExcludes = [NSSet setWithObjects: @"RoomPlanWrapper", nil]; +}]; +``` + If you can't upgrade the Sentry Cocoa SDK to version `8.23.0`, you can also disable swizzling, as shown below. However, this would also disable some useful features, such as automatic tracing and network breadcrumbs. @@ -118,6 +124,14 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.enableSwizzling = NO; +}]; +``` + ## Xcode Compiler Error: Invalid Version The errors, `error: invalid version number in '-target arm64-apple-ios9999'` and `invalid version number in '-target arm64-apple-ios10.15-macabi'`, are due to a bug in Xcode. To fix this issue, update the Cocoa SDK to version 8.26.0 or above, or stay on version 8.21.0. @@ -173,21 +187,21 @@ While it seems to be related to Sentry, it is actually caused by the user script Since Cocoa SDK version [8.45.0](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8450) and above, you might see a compilation error `'required' initializer 'init(from:)' must be provided by subclass ...`, when you subclass any of the following classes: -* `SentryBreadcrumb` -* `SentryDebugMeta` -* `SentryEvent` -* `SentryException` -* `SentryFrame` -* `SentryGeo` -* `SentryId` -* `SentryMechanism` -* `SentryMechanismMeta` -* `SentryMessage` -* `SentryNSError` -* `SentryRequest` -* `SentryStacktrace` -* `SentryThread` -* `SentryUser` +- `SentryBreadcrumb` +- `SentryDebugMeta` +- `SentryEvent` +- `SentryException` +- `SentryFrame` +- `SentryGeo` +- `SentryId` +- `SentryMechanism` +- `SentryMechanismMeta` +- `SentryMessage` +- `SentryNSError` +- `SentryRequest` +- `SentryStacktrace` +- `SentryThread` +- `SentryUser` You can fix this by not subclassing the affected classes. Strictly speaking, this is a breaking change, but these classes are not intended to be subclassed. If you have a strong reason to subclass them, please open a [GitHub issue](https://github.com/getsentry/sentry-cocoa/issues/new/choose). diff --git a/docs/platforms/apple/common/usage/in-app-frames/index.mdx b/docs/platforms/apple/common/usage/in-app-frames/index.mdx index 533e937683957..51a0c9a6a687c 100644 --- a/docs/platforms/apple/common/usage/in-app-frames/index.mdx +++ b/docs/platforms/apple/common/usage/in-app-frames/index.mdx @@ -23,7 +23,6 @@ If you use dynamic frameworks such as Sentry, the Sentry SDK will mark them as ` **Note:** `inAppExclude` was removed in version 9.0.0 as it had no effect. - ```swift {tabTitle:Swift} import Sentry @@ -46,6 +45,17 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + + // The SDK marks all frameworks starting with MyBusinessLogic as inApp + [options addInAppInclude:@"MyBusinessLogic"]; +}]; +``` + ## Static Frameworks Because static frameworks end up in the main executable, if you're using one, the Sentry SDK won't be able to detect if a frame of the main executable diff --git a/docs/platforms/apple/guides/ios/manual-setup.mdx b/docs/platforms/apple/guides/ios/manual-setup.mdx index 58eb27f87eb14..5a42410fa36ae 100644 --- a/docs/platforms/apple/guides/ios/manual-setup.mdx +++ b/docs/platforms/apple/guides/ios/manual-setup.mdx @@ -22,7 +22,6 @@ The Package has a few products you can depend on, but the recommended one is `Se We recommend initializing the SDK on the main thread as soon as possible – in your AppDelegate `application:didFinishLaunchingWithOptions` method, for example: - ```swift {tabTitle:Swift} import Sentry // Make sure you import Sentry @@ -62,8 +61,25 @@ func application(_ application: UIApplication, } ``` -If you're using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [App conformer's initializer](): +```objc {tabTitle:Objective-C (SentryObjC)} +#import +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + [SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.debug = YES; // Enabled debug when first installing is always helpful + + // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. + // We recommend adjusting this value in production. + options.tracesSampleRate = @1.0; + }]; + + return YES; +} +``` + +If you're using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [App conformer's initializer](): ```swift import Sentry diff --git a/platform-includes/capture-error/apple.mdx b/platform-includes/capture-error/apple.mdx index 69f4ec8186d1d..c7b8535cbe336 100644 --- a/platform-includes/capture-error/apple.mdx +++ b/platform-includes/capture-error/apple.mdx @@ -9,7 +9,7 @@ enum MyCustomError: Error { func thisFunctionThrows() throws { throw MyCustomError.myFirstIssue -} +} do { try thisFunctionThrows() @@ -39,6 +39,27 @@ if (error) { } ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +- (void)thisFunctionReturnsAnError:(NSError **)error { + *error = [NSError errorWithDomain:@"com.example.myapp" + code:1001 + userInfo:@{ + NSLocalizedDescriptionKey: @"Something went wrong." + }]; +} + +// ... Your code + +NSError *error = nil; +[self thisFunctionReturnsAnError:&error]; + +if (error) { + [SentryObjCSDK captureError:error]; +} +``` + ### Swift Errors For Swift Errors conforming to the [Error Protocol](https://developer.apple.com/documentation/swift/error) the SDK sends the domain, code and the description of the Swift error. @@ -159,6 +180,7 @@ SentrySDK.start { options in options.enableUncaughtNSExceptionReporting = true } ``` + ```objc {tabTitle:Objective-C} @import Sentry; @@ -168,4 +190,13 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableUncaughtNSExceptionReporting = YES; +}]; +``` + diff --git a/platform-includes/capture-message/apple.mdx b/platform-includes/capture-message/apple.mdx index 23deaa90d6800..be579e4f6ef19 100644 --- a/platform-includes/capture-message/apple.mdx +++ b/platform-includes/capture-message/apple.mdx @@ -9,3 +9,9 @@ SentrySDK.capture(message: "My first test message") [SentrySDK captureMessage:@"My first test message"]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK captureMessage:@"My first test message"]; +``` diff --git a/platform-includes/configuration/auto-session-tracking/apple.mdx b/platform-includes/configuration/auto-session-tracking/apple.mdx index b072669078621..d508c105b4883 100644 --- a/platform-includes/configuration/auto-session-tracking/apple.mdx +++ b/platform-includes/configuration/auto-session-tracking/apple.mdx @@ -2,7 +2,6 @@ To benefit from the health data, you must use _at least_ version 5.0.0 of the Co By default, the session is terminated once the application is in the background for more than 30 seconds. You can change the time out with the option named `sessionTrackingIntervalMillis`. It takes the amount in milliseconds. For example, to configure it to be 60 seconds: - ```swift {tabTitle:Swift} import Sentry @@ -21,8 +20,16 @@ SentrySDK.start { options in }]; ``` -If you'd like to opt out of this feature, you can do so using options: +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithOptions:@{ + @"dsn": @"___PUBLIC_DSN___", + @"sessionTrackingIntervalMillis": @60000 +}]; +``` +If you'd like to opt out of this feature, you can do so using options: ```swift {tabTitle:Swift} import Sentry @@ -43,3 +50,13 @@ SentrySDK.start { options in @"enableAutoSessionTracking": @(NO) }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithOptions:@{ + @"dsn": @"___PUBLIC_DSN___", + // If you prefer NOT to track release health. + @"enableAutoSessionTracking": @(NO) +}]; +``` diff --git a/platform-includes/configuration/before-send-fingerprint/apple.mdx b/platform-includes/configuration/before-send-fingerprint/apple.mdx index 56460e137f7c1..0769f91080700 100644 --- a/platform-includes/configuration/before-send-fingerprint/apple.mdx +++ b/platform-includes/configuration/before-send-fingerprint/apple.mdx @@ -25,3 +25,17 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + if ([event.message.formatted isEqualToString:@"database unavailable"]) { + event.fingerprint = @[@"database-connection-error"]; + } + return event; + }; +}]; +``` diff --git a/platform-includes/configuration/before-send-span/apple.mdx b/platform-includes/configuration/before-send-span/apple.mdx index 982be8de5844e..419b9d05db489 100644 --- a/platform-includes/configuration/before-send-span/apple.mdx +++ b/platform-includes/configuration/before-send-span/apple.mdx @@ -29,3 +29,19 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeSendSpan = ^id _Nullable (id _Nonnull span) { + // Modify or drop the span here + if ([span.description isEqualToString:@"unimportant span"]) { + // Don't send the span to Sentry + return nil; + } + return span; + }; +}]; +``` diff --git a/platform-includes/configuration/before-send/apple.mdx b/platform-includes/configuration/before-send/apple.mdx index f854efbe516d1..a229d00625c8a 100644 --- a/platform-includes/configuration/before-send/apple.mdx +++ b/platform-includes/configuration/before-send/apple.mdx @@ -21,3 +21,15 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + // modify event here or return nil to discard the event + return event; + }; +}]; +``` diff --git a/platform-includes/configuration/config-intro/apple.mdx b/platform-includes/configuration/config-intro/apple.mdx index 6bdfe05da1a94..b40796680421b 100644 --- a/platform-includes/configuration/config-intro/apple.mdx +++ b/platform-includes/configuration/config-intro/apple.mdx @@ -28,3 +28,17 @@ func application(_ application: UIApplication, return YES; } ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + [SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.debug = YES; // Enabled debug when first installing is always helpful + }]; + + return YES; +} +``` diff --git a/platform-includes/configuration/sample-rate/apple.mdx b/platform-includes/configuration/sample-rate/apple.mdx index 231a648a67063..86b2f0394e75c 100644 --- a/platform-includes/configuration/sample-rate/apple.mdx +++ b/platform-includes/configuration/sample-rate/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.start { options in options.sampleRate = @0.25; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.sampleRate = @0.25; +}]; +``` diff --git a/platform-includes/enriching-events/attach-screenshots/apple.mdx b/platform-includes/enriching-events/attach-screenshots/apple.mdx index e0ec617ab0ebd..a69333530b83c 100644 --- a/platform-includes/enriching-events/attach-screenshots/apple.mdx +++ b/platform-includes/enriching-events/attach-screenshots/apple.mdx @@ -14,6 +14,14 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.attachScreenshot = YES; +}]; +``` + ### Customize Screenshot Capturing @@ -22,7 +30,6 @@ Requires Cocoa SDK version `8.27.0` or higher. - The `beforeCaptureScreenshot` also allows you to customize the behavior based on event data, so you can decide when to capture a screenshot and when not to. The callback doesn't work for crash events. ```swift {tabTitle:Swift} @@ -48,3 +55,15 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeCaptureScreenshot = ^BOOL(SentryObjCEvent * _Nonnull event) { + // Return NO to not capture a screenshot for the event. + return NO; + }; +}]; +``` diff --git a/platform-includes/enriching-events/attach-viewhierarchy/apple.mdx b/platform-includes/enriching-events/attach-viewhierarchy/apple.mdx index 7739f12d06f87..83f39a38a245a 100644 --- a/platform-includes/enriching-events/attach-viewhierarchy/apple.mdx +++ b/platform-includes/enriching-events/attach-viewhierarchy/apple.mdx @@ -14,6 +14,14 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.attachViewHierarchy = YES; +}]; +``` + ### Customize View Hierarchy Capturing @@ -22,7 +30,6 @@ Requires Cocoa SDK version `8.33.0` or higher. - The `beforeCaptureViewHierarchy` also allows you to customize the behavior based on event data, so you can decide when to capture a view hierarchy and when not to. The callback doesn't work for crash events. ```swift {tabTitle:Swift} @@ -48,3 +55,15 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.beforeCaptureViewHierarchy = ^BOOL(SentryObjCEvent * _Nonnull event) { + // Return NO to not capture a view hierarchy for the event. + return NO; + }; +}]; +``` diff --git a/platform-includes/enriching-events/attachment-init-with-bytes/apple.mdx b/platform-includes/enriching-events/attachment-init-with-bytes/apple.mdx index 554ecb3773f47..4c0e48c544c9d 100644 --- a/platform-includes/enriching-events/attachment-init-with-bytes/apple.mdx +++ b/platform-includes/enriching-events/attachment-init-with-bytes/apple.mdx @@ -10,3 +10,10 @@ let attachment = Attachment(data: data, filename: "file.log") SentryAttachment *attachment = [[SentryAttachment alloc] initWithData:data filename:@"file.log"]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCAttachment *attachment = + [[SentryObjCAttachment alloc] initWithData:data filename:@"file.log"]; +``` diff --git a/platform-includes/enriching-events/attachment-init-with-path/apple.mdx b/platform-includes/enriching-events/attachment-init-with-path/apple.mdx index 709f0cd25ae63..b7b8a98c923d4 100644 --- a/platform-includes/enriching-events/attachment-init-with-path/apple.mdx +++ b/platform-includes/enriching-events/attachment-init-with-path/apple.mdx @@ -10,3 +10,10 @@ let attachment = Attachment(path: "your/path/file.log") SentryAttachment *attachment = [[SentryAttachment alloc] initWithPath:@"your/path/file.log"]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCAttachment *attachment = + [[SentryObjCAttachment alloc] initWithPath:@"your/path/file.log"]; +``` diff --git a/platform-includes/enriching-events/attachment-max-size/apple.mdx b/platform-includes/enriching-events/attachment-max-size/apple.mdx index 730c2d5508b1b..83ba64fbe78af 100644 --- a/platform-includes/enriching-events/attachment-max-size/apple.mdx +++ b/platform-includes/enriching-events/attachment-max-size/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.start { options in options.maxAttachmentSize = 5 * 1024 * 1024; // 5 MiB }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.maxAttachmentSize = 5 * 1024 * 1024; // 5 MiB +}]; +``` diff --git a/platform-includes/enriching-events/attachment-upload/apple.mdx b/platform-includes/enriching-events/attachment-upload/apple.mdx index c9ce4ee90be41..3d8f68c5bda46 100644 --- a/platform-includes/enriching-events/attachment-upload/apple.mdx +++ b/platform-includes/enriching-events/attachment-upload/apple.mdx @@ -40,3 +40,25 @@ SentryAttachment *fileAttachment = [scope clearAttachments]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCAttachment *fileAttachment = + [[SentryObjCAttachment alloc] initWithPath:@"your/path/file.log"]; + +// Global Scope +[SentryObjCSDK configureScope:^(SentryObjCScope *_Nonnull scope) { + [scope addAttachment:fileAttachment]; +}]; + +// Local Scope +[SentryObjCSDK captureMessage:@"my message" withScopeBlock:^(SentryObjCScope * _Nonnull scope) { + [scope addAttachment:fileAttachment]; +}]; + +// Clear all attachments in the global Scope +[SentryObjCSDK configureScope:^(SentryObjCScope *_Nonnull scope) { + [scope clearAttachments]; +}]; +``` diff --git a/platform-includes/enriching-events/breadcrumbs/before-breadcrumb/apple.mdx b/platform-includes/enriching-events/breadcrumbs/before-breadcrumb/apple.mdx index c607040358112..7e0e2c6cbe286 100644 --- a/platform-includes/enriching-events/breadcrumbs/before-breadcrumb/apple.mdx +++ b/platform-includes/enriching-events/breadcrumbs/before-breadcrumb/apple.mdx @@ -17,3 +17,13 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.beforeBreadcrumb = ^SentryObjCBreadcrumb * _Nullable(SentryObjCBreadcrumb * _Nonnull crumb) { + return crumb; + }; +}]; +``` diff --git a/platform-includes/enriching-events/breadcrumbs/breadcrumbs-example/apple.mdx b/platform-includes/enriching-events/breadcrumbs/breadcrumbs-example/apple.mdx index 72a356329deb1..faa00383a8b17 100644 --- a/platform-includes/enriching-events/breadcrumbs/breadcrumbs-example/apple.mdx +++ b/platform-includes/enriching-events/breadcrumbs/breadcrumbs-example/apple.mdx @@ -17,3 +17,13 @@ crumb.category = @"auth"; crumb.message = [NSString stringWithFormat:@"Authenticated user %@", user.email]; [SentrySDK addBreadcrumb:crumb]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCBreadcrumb *crumb = [[SentryObjCBreadcrumb alloc] init]; +crumb.level = SentryObjCLevelInfo; +crumb.category = @"auth"; +crumb.message = [NSString stringWithFormat:@"Authenticated user %@", user.email]; +[SentryObjCSDK addBreadcrumb:crumb]; +``` diff --git a/platform-includes/enriching-events/scopes/configure-scope/apple.mdx b/platform-includes/enriching-events/scopes/configure-scope/apple.mdx index 523453064a088..462cfd597c6fb 100644 --- a/platform-includes/enriching-events/scopes/configure-scope/apple.mdx +++ b/platform-includes/enriching-events/scopes/configure-scope/apple.mdx @@ -22,6 +22,17 @@ SentrySDK.configureScope { scope in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope * _Nonnull scope) { + [scope setTagValue:@"my-tag" forKey:@"my value"]; + SentryObjCUser *user = [[SentryObjCUser alloc] init]; + user.email = @"john.doe@example.com"; + [scope setUser:user]; +}]; +``` + ### Passing a Scope Instance Setting an instance of Scope is helpful when you want to completely control what should be attached to the event. diff --git a/platform-includes/enriching-events/scopes/scope-callback-param/apple.mdx b/platform-includes/enriching-events/scopes/scope-callback-param/apple.mdx index d143ff17501d1..8ecb8d4f52390 100644 --- a/platform-includes/enriching-events/scopes/scope-callback-param/apple.mdx +++ b/platform-includes/enriching-events/scopes/scope-callback-param/apple.mdx @@ -23,3 +23,16 @@ SentrySDK.capture(error: error) // will not be tagged with my-tag [SentrySDK captureError:error]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK captureError:error withScopeBlock:^(SentryObjCScope * _Nonnull scope) { + [scope setLevel:SentryObjCLevelWarning]; + // will be tagged with my-tag="my value" + [scope setTagValue:@"my value" forKey:@"my-tag"]; +}]; + +// will not be tagged with my-tag +[SentryObjCSDK captureError:error]; +``` diff --git a/platform-includes/enriching-events/set-context/apple.mdx b/platform-includes/enriching-events/set-context/apple.mdx index 4673d47639441..39a1eb7bdb137 100644 --- a/platform-includes/enriching-events/set-context/apple.mdx +++ b/platform-includes/enriching-events/set-context/apple.mdx @@ -21,3 +21,15 @@ SentrySDK.configureScope { scope in } forKey:@"character"]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope *_Nonnull scope) { + [scope setContextValue:@{ + @"name" : @"Mighty Fighter", + @"age" : @19, + @"attack_type" : @"melee" + } forKey:@"character"]; +}]; +``` diff --git a/platform-includes/enriching-events/set-tag/apple.mdx b/platform-includes/enriching-events/set-tag/apple.mdx index 1c4cd2ab124c3..4888f6b5d7940 100644 --- a/platform-includes/enriching-events/set-tag/apple.mdx +++ b/platform-includes/enriching-events/set-tag/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.configureScope { scope in [scope setTagValue:@"de-at" forKey:@"page_locale"]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope * _Nonnull scope) { + [scope setTagValue:@"de-at" forKey:@"page_locale"]; +}]; +``` diff --git a/platform-includes/enriching-events/set-user/apple.mdx b/platform-includes/enriching-events/set-user/apple.mdx index 4a8e7b1fb50eb..47e293ee63f15 100644 --- a/platform-includes/enriching-events/set-user/apple.mdx +++ b/platform-includes/enriching-events/set-user/apple.mdx @@ -15,3 +15,12 @@ user.email = @"john.doe@example.com"; // Start the SDK before setting the user, otherwise it will be ignored. [SentrySDK setUser:user]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCUser *user = [[SentryObjCUser alloc] init]; +user.email = @"john.doe@example.com"; +// Start the SDK before setting the user, otherwise it will be ignored. +[SentryObjCSDK setUser:user]; +``` diff --git a/platform-includes/enriching-events/unset-user/apple.mdx b/platform-includes/enriching-events/unset-user/apple.mdx index 46d04a60da3e7..1290358eab4cf 100644 --- a/platform-includes/enriching-events/unset-user/apple.mdx +++ b/platform-includes/enriching-events/unset-user/apple.mdx @@ -9,3 +9,9 @@ SentrySDK.setUser(nil) [SentrySDK setUser:nil]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK setUser:nil]; +``` diff --git a/platform-includes/getting-started-config/apple.mdx b/platform-includes/getting-started-config/apple.mdx index 7890ed98b5939..5ba696e2c1641 100644 --- a/platform-includes/getting-started-config/apple.mdx +++ b/platform-includes/getting-started-config/apple.mdx @@ -1,6 +1,5 @@ We recommend initializing the SDK on the main thread as soon as possible, such as in your AppDelegate `application:didFinishLaunchingWithOptions` method: - ```swift {tabTitle:Swift} import Sentry // Make sure you import Sentry @@ -40,8 +39,25 @@ func application(_ application: UIApplication, } ``` -When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [App conformer's initializer](): +```objc {tabTitle:Objective-C (SentryObjC)} +#import +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + [SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.debug = YES; // Enabled debug when first installing is always helpful + + // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. + // We recommend adjusting this value in production. + options.tracesSampleRate = @1.0; + }]; + + return YES; +} +``` + +When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [App conformer's initializer](): ```swift import Sentry @@ -61,6 +77,6 @@ struct SwiftUIApp: App { } ``` -{/**/} +{/* */} diff --git a/platform-includes/logs/options/apple.mdx b/platform-includes/logs/options/apple.mdx index 9755c2ccdc3b8..3f3401c4c8f34 100644 --- a/platform-includes/logs/options/apple.mdx +++ b/platform-includes/logs/options/apple.mdx @@ -42,6 +42,23 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableLogs = YES; + + options.beforeSendLog = ^SentryLog* (SentryLog *log) { + if (log.level == SentryLogLevelInfo) { + // Filter out all info logs + return nil; + } + return log; + }; +}]; +``` + Before 9.0.0: ```swift {tabTitle:Swift} @@ -76,6 +93,22 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.experimental.enableLogs = YES; + + options.beforeSendLog = ^SentryLog* (SentryLog *log) { + if (log.level == SentryLogLevelInfo) { + return nil; + } + return log; + }; +}]; +``` + The `beforeSendLog` function receives a log object, and should return the log object if you want it to be sent to Sentry, or `nil` if you want to discard it. The log object has the following properties: diff --git a/platform-includes/logs/setup/apple.mdx b/platform-includes/logs/setup/apple.mdx index d2dfd9ea3ed45..331c97b8ae366 100644 --- a/platform-includes/logs/setup/apple.mdx +++ b/platform-includes/logs/setup/apple.mdx @@ -18,6 +18,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableLogs = YES; +}]; +``` + Before 9.0.0, this option was experimental: ```swift {tabTitle:Swift} @@ -38,3 +47,12 @@ SentrySDK.start { options in options.experimental.enableLogs = YES; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.experimental.enableLogs = YES; +}]; +``` diff --git a/platform-includes/logs/usage/apple.mdx b/platform-includes/logs/usage/apple.mdx index 3a261f8615dc8..9562bf4b18d1f 100644 --- a/platform-includes/logs/usage/apple.mdx +++ b/platform-includes/logs/usage/apple.mdx @@ -58,6 +58,34 @@ SentryLogger *logger = SentrySDK.logger; }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCLogger *logger = SentryObjCSDK.logger; + +// Log messages without attributes +[logger trace:@"Starting database connection"]; +[logger debug:@"Cache miss for user"]; +[logger info:@"Updated profile"]; + +// Log messages with attributes +[logger trace:@"Starting database connection" attributes:@{@"database": @"users"}]; +[logger debug:@"Cache miss for user" attributes:@{@"userId": @123}]; +[logger info:@"Updated profile" attributes:@{@"profileId": @345}]; +[logger warn:@"Rate limit reached for endpoint" attributes:@{ + @"endpoint": @"/api/results/", + @"isEnterprise": @NO +}]; +[logger error:@"Failed to process payment" attributes:@{ + @"orderId": @"order_123", + @"amount": @99.99 +}]; +[logger fatal:@"Database connection pool exhausted" attributes:@{ + @"database": @"users", + @"activeConnections": @100 +}]; +``` + ### String Interpolation (Swift Only) Swift supports automatic extraction of interpolated values as attributes. When you use string interpolation in your log messages, supported types (Strings, Int, Double, and Bool) are automatically extracted and added as attributes with the key format `sentry.message.parameter.{index}`. diff --git a/platform-includes/metrics/options/apple.mdx b/platform-includes/metrics/options/apple.mdx index 9434d02d1aad4..3414915419119 100644 --- a/platform-includes/metrics/options/apple.mdx +++ b/platform-includes/metrics/options/apple.mdx @@ -22,6 +22,15 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.enableMetrics = NO; // Metrics are enabled by default +}]; +``` + ### Filtering and Modifying Metrics Use the `beforeSendMetric` callback to filter or modify metrics before they're sent to Sentry. This is useful for: @@ -34,6 +43,7 @@ Use the `beforeSendMetric` callback to filter or modify metrics before they're s The callback receives a `SentryMetric` struct and must return either a modified metric or `nil` to drop it. **Available `SentryMetric` properties:** + - `name`: The metric name (e.g., "api.response_time") - `value`: The metric value (`SentryMetricValue` - counter, distribution, or gauge) - `unit`: The unit of measurement (`SentryUnit?`) diff --git a/platform-includes/pass-scope/apple.mdx b/platform-includes/pass-scope/apple.mdx index 93d66e1f26514..ab46cd01456ef 100644 --- a/platform-includes/pass-scope/apple.mdx +++ b/platform-includes/pass-scope/apple.mdx @@ -23,3 +23,16 @@ SentryScope *scope = [[SentryScope alloc] init]; // If you just want to mutate what's in the scope use the callback, see: captureError [SentrySDK captureException:exception withScope:scope]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +NSException *exception = [[NSException alloc] initWithName:@"My Custom exception" reason:@"User clicked the button" userInfo:nil]; +SentryObjCScope *scope = [[SentryObjCScope alloc] init]; +[scope setLevel:SentryObjCLevelFatal]; +// By explicitly just passing the scope, only the data in this scope object will be added to the event +// The global scope (calls to configureScope) will be ignored +// Only do this if you have mastered this SDK, otherwise, you risk losing useful info +// If you just want to mutate what's in the scope use the callback, see: captureError +[SentryObjCSDK captureException:exception withScope:scope]; +``` diff --git a/platform-includes/performance/add-spans-example/apple.mdx b/platform-includes/performance/add-spans-example/apple.mdx index 9477778c9fb98..f732f67bfaae3 100644 --- a/platform-includes/performance/add-spans-example/apple.mdx +++ b/platform-includes/performance/add-spans-example/apple.mdx @@ -64,4 +64,36 @@ func performCheckout() } ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +// Let's say this method is called in a background thread when a user clicks on the checkout button of your shop +-(void) performCheckout +{ + // This will create a new Transaction for you + + SentryObjCSpan *transaction = [SentryObjCSDK startTransactionWithName:@"checkout", + operation:@"perform-checkout" + ); + + // Validate the cart + SentryObjCSpan *validationSpan = [transaction startChildWithOperation:@"validation", + description:@"validating shopping cart"]; + + [self validateShoppingCart]; //Some long process, maybe a sync http request. + + [validationSpan finish]; + + // Process the order + SentryObjCSpan *processSpan = [transaction startChildWithOperation:@"process", + description:@"processing shopping cart"]; + + [self processShoppingCart]; //Another time consuming process. + + [processSpan finish]; + + [transaction finish]; +} +``` + This example will send a transaction named `checkout` to Sentry. The transaction will contain a `validation` span that measures how long `validateShoppingCart()` took and a `process` span that measures `processShoppingCart()`. Finally, the call to `transaction.finish()` will finish the transaction and send it to Sentry. diff --git a/platform-includes/performance/always-inherit-sampling-decision/apple.mdx b/platform-includes/performance/always-inherit-sampling-decision/apple.mdx index ddcb8adc301da..5df11de796fc1 100644 --- a/platform-includes/performance/always-inherit-sampling-decision/apple.mdx +++ b/platform-includes/performance/always-inherit-sampling-decision/apple.mdx @@ -19,3 +19,14 @@ SentryTracesSamplerCallback callback = ^(SentrySamplingContext *context) { // the rest of sampling logic }; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCTracesSamplerCallback callback = ^(SentryObjCSamplingContext *context) { + if (context.transactionContext.parentSampled != SentryObjCSampleDecisionUndecided) { + return context.transactionContext.parentSampled == SentryObjCSampleDecisionYes ? @1.0 : @0.0; + } + // the rest of sampling logic +}; +``` diff --git a/platform-includes/performance/configure-sample-rate/apple.mdx b/platform-includes/performance/configure-sample-rate/apple.mdx index 84886c1564561..8ee75e382a16e 100644 --- a/platform-includes/performance/configure-sample-rate/apple.mdx +++ b/platform-includes/performance/configure-sample-rate/apple.mdx @@ -42,3 +42,25 @@ SentrySDK.start { options in + }; }]; ``` + +```objc {diff, tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions * options) { + options.dsn = @"___PUBLIC_DSN___"; + ++ // Example uniform sample rate: capture 100% of transactions ++ // In Production you will probably want a smaller number such as 0.5 for 50% ++ options.tracesSampleRate = @1.0; + ++ // OR if you prefer, determine traces sample rate based on the sampling context ++ options.tracesSampler = ^NSNumber * (SentryObjCSamplingContext * samplingContext) { ++ // Don't miss any transactions for VIP users ++ if ([samplingContext.customSamplingContext[@"vip"] boolValue] == YES) { ++ return @1.0; ++ } else { ++ return @0.25; // 25% for everything else ++ } ++ }; +}]; +``` diff --git a/platform-includes/performance/connect-errors-spans/apple.mdx b/platform-includes/performance/connect-errors-spans/apple.mdx index 0816a2dccd175..be7e329b03b3c 100644 --- a/platform-includes/performance/connect-errors-spans/apple.mdx +++ b/platform-includes/performance/connect-errors-spans/apple.mdx @@ -29,3 +29,17 @@ if (processItem(error: &error)) { [transaction finishWithStatus:kSentrySpanStatusInternalError]; } ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCSpan *transaction = [SentryObjCSDK startTransactionWithName:@"Transaction Name" operation:@"operation" bindToScope:YES]; +NSError * error; + +if (processItem(error: &error)) { + [transaction finish]; +} else { + [SentryObjCSDK captureError:error]; + [transaction finishWithStatus:SentryObjCSpanStatusInternalError]; +} +``` diff --git a/platform-includes/performance/create-transaction-bound-to-scope/apple.mdx b/platform-includes/performance/create-transaction-bound-to-scope/apple.mdx index 620af4cae4e83..6b275e0aa845d 100644 --- a/platform-includes/performance/create-transaction-bound-to-scope/apple.mdx +++ b/platform-includes/performance/create-transaction-bound-to-scope/apple.mdx @@ -55,3 +55,29 @@ id transaction = [innerSpan finish]; } ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCSpan *transaction = + [SentryObjCSDK startTransactionWithName:@"processOrderBatch" + operation:@"task" + bindToScope:YES]; + + +[self processOrderBatch]; +[transaction finish]; + +- (void)processOrderBatch { + SentryObjCSpan *span = SentryObjCSDK.span; + + if (span == nil) { + span = [SentryObjCSDK startTransactionWithName:@"processOrderBatch" + operation:@"task"]; + } + + SentryObjCSpan *innerSpan = [span startChildWithOperation:@"subtask"]; + // omitted code + [innerSpan finish]; +} +``` diff --git a/platform-includes/performance/custom-performance-metrics/apple.mdx b/platform-includes/performance/custom-performance-metrics/apple.mdx index 463a824b8a299..de1755f25a1ff 100644 --- a/platform-includes/performance/custom-performance-metrics/apple.mdx +++ b/platform-includes/performance/custom-performance-metrics/apple.mdx @@ -30,3 +30,19 @@ if (span != nil) { [span setMeasurement:@"screen_load_count" value:@4]; } ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCSpan *span = SentryObjCSDK.span; +if (span != nil) { + // Record amount of memory used + [span setMeasurement:@"memory_used" value:@64 unit:SentryObjCMeasurementUnitInformation.megabyte]; + + // Record time it took to load user profile + [span setMeasurement:@"user_profile_loading_time" value:@1.3 unit:SentryObjCMeasurementUnitDuration.second]; + + // Record number of times the screen was loaded + [span setMeasurement:@"screen_load_count" value:@4]; +} +``` diff --git a/platform-includes/performance/custom-sampling-context/apple.mdx b/platform-includes/performance/custom-sampling-context/apple.mdx index 4c95437c11bca..59afd6a208ba8 100644 --- a/platform-includes/performance/custom-sampling-context/apple.mdx +++ b/platform-includes/performance/custom-sampling-context/apple.mdx @@ -37,3 +37,23 @@ id transaction = transaction.context.operation = @"http"; transaction.context.spanDescription = @"search results"; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +// The following data will take part in the sampling decision +NSDictionary *samplingContext = @{ + @"user_id": @12312012, + @"search_results": searchResults +}; + +SentryObjCSpan *transaction = +[SentryObjCSDK startTransactionWithContext: [[SentryObjCTransactionContext alloc] initWithName:@"GET /search" + operation:@"http"] + customSamplingContext: samplingContext]; + +// The following is set on transaction, so does not take part in +// the sampling decision +transaction.context.operation = @"http"; +transaction.context.spanDescription = @"search results"; +``` diff --git a/platform-includes/performance/enable-manual-instrumentation/apple.mdx b/platform-includes/performance/enable-manual-instrumentation/apple.mdx index e60f5695d29e1..3ba31ac6c24ce 100644 --- a/platform-includes/performance/enable-manual-instrumentation/apple.mdx +++ b/platform-includes/performance/enable-manual-instrumentation/apple.mdx @@ -37,3 +37,21 @@ id span = [transaction startChildWithOperation:@"child-operation"]; [span finish]; // Remember that only finished spans will be sent with the transaction [transaction finish]; // Finishing the transaction will send it to Sentry ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +// Transaction can be started by providing, at minimum, the name and the operation +SentryObjCSpan *transaction = [SentryObjCSDK startTransactionWithName:@"transaction-name" + operation:@"transaction-operation"]; + +// Transactions can have child spans (and those spans can have child spans as well) +SentryObjCSpan *span = [transaction startChildWithOperation:@"child-operation"]; + +// ... +// (Perform the operation represented by the span/transaction) +// ... + +[span finish]; // Remember that only finished spans will be sent with the transaction +[transaction finish]; // Finishing the transaction will send it to Sentry +``` diff --git a/platform-includes/performance/force-sampling-decision/apple.mdx b/platform-includes/performance/force-sampling-decision/apple.mdx index 371b2237c49f6..2d826b37a6f14 100644 --- a/platform-includes/performance/force-sampling-decision/apple.mdx +++ b/platform-includes/performance/force-sampling-decision/apple.mdx @@ -15,3 +15,14 @@ SentryTransactionContext *transactionContext = [[TransactionContext alloc] initW id transaction = [SentrySDK startTransactionWithContext:transactionContext]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +// IsSampled -> yes +SentryObjCTransactionContext *transactionContext = [[SentryObjCTransactionContext alloc] initWithName:@"GET /search" + operation:@"http" + sampled:SentryObjCSampleDecisionYes]; + +SentryObjCSpan *transaction = [SentryObjCSDK startTransactionWithContext:transactionContext]; +``` diff --git a/platform-includes/performance/improving-data/apple.mdx b/platform-includes/performance/improving-data/apple.mdx index fbfb15da0cdea..0d19bdd4cd845 100644 --- a/platform-includes/performance/improving-data/apple.mdx +++ b/platform-includes/performance/improving-data/apple.mdx @@ -14,6 +14,7 @@ transaction.setData(value: ["value1", "value2", "value3"], key: "my-data-attribu transaction.setData(value: [42, 43, 44], key: "my-data-attribute-5") transaction.setData(value: [true, false, true], key: "my-data-attribute-6") ``` + ```objc {tabTitle:Objective-C} id transaction = [SentrySDK startTransactionWithName:@"processOrderBatch" operation:@"task"]; [transaction setDataValue:@"value1" forKey:@"my-data-attribute-1"]; @@ -25,6 +26,19 @@ id transaction = [SentrySDK startTransactionWithName:@"processOrderB [transaction setDataValue:@[@(YES), @(NO), @(YES)] forKey:@"my-data-attribute-6"]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCSpan *transaction = [SentryObjCSDK startTransactionWithName:@"processOrderBatch" operation:@"task"]; +[transaction setDataValue:@"value1" forKey:@"my-data-attribute-1"]; +[transaction setDataValue:@(42) forKey:@"my-data-attribute-2"]; +[transaction setDataValue:@(YES) forKey:@"my-data-attribute-3"]; + +[transaction setDataValue:@[@"value1", @"value2", @"value3"] forKey:@"my-data-attribute-4"]; +[transaction setDataValue:@[@(42), @(43), @(44)] forKey:@"my-data-attribute-5"]; +[transaction setDataValue:@[@(YES), @(NO), @(YES)] forKey:@"my-data-attribute-6"]; +``` + ### Adding Data Attributes to Spans You can add data attributes to your spans. This data is visible in the trace explorer in Sentry. Data attributes can be of type `String`, `Number` or `Boolean`, as well as (non-mixed) arrays of these types: @@ -39,6 +53,7 @@ span.setData(value: ["value1", "value2", "value3"], key: "my-data-attribute-4") span.setData(value: [42, 43, 44], key: "my-data-attribute-5") span.setData(value: [true, false, true], key: "my-data-attribute-6") ``` + ```objc {tabTitle:Objective-C} id span = [transaction startChildWithOperation:@"task"]; [span setDataValue:@"value1" forKey:@"my-data-attribute-1"]; @@ -49,3 +64,14 @@ id span = [transaction startChildWithOperation:@"task"]; [span setDataValue:@[@(42), @(43), @(44)] forKey:@"my-data-attribute-5"]; [span setDataValue:@[@(YES), @(NO), @(YES)] forKey:@"my-data-attribute-6"]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +SentryObjCSpan *span = [transaction startChildWithOperation:@"task"]; +[span setDataValue:@"value1" forKey:@"my-data-attribute-1"]; +[span setDataValue:@(42) forKey:@"my-data-attribute-2"]; +[span setDataValue:@(YES) forKey:@"my-data-attribute-3"]; + +[span setDataValue:@[@"value1", @"value2", @"value3"] forKey:@"my-data-attribute-4"]; +[span setDataValue:@[@(42), @(43), @(44)] forKey:@"my-data-attribute-5"]; +[span setDataValue:@[@(YES), @(NO), @(YES)] forKey:@"my-data-attribute-6"]; +``` diff --git a/platform-includes/performance/retrieve-transaction/apple.mdx b/platform-includes/performance/retrieve-transaction/apple.mdx index c75ac6f7d6d56..8cdcb5ecec453 100644 --- a/platform-includes/performance/retrieve-transaction/apple.mdx +++ b/platform-includes/performance/retrieve-transaction/apple.mdx @@ -25,3 +25,15 @@ if (span == nil) { span = [span startChildWithOperation: @"subtask"]; } ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCSpan *span = SentryObjCSDK.span; + +if (span == nil) { + span = [SentryObjCSDK startTransactionWithName:@"task" operation:@"op"]; +} else { + span = [span startChildWithOperation: @"subtask"]; +} +``` diff --git a/platform-includes/performance/traces-sample-rate/apple.mdx b/platform-includes/performance/traces-sample-rate/apple.mdx index 31b92d5718ba7..eaa104bb0a97c 100644 --- a/platform-includes/performance/traces-sample-rate/apple.mdx +++ b/platform-includes/performance/traces-sample-rate/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.start { options in options.tracesSampleRate = @0.2; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions * options) { + options.tracesSampleRate = @0.2; +}]; +``` diff --git a/platform-includes/performance/traces-sampler-as-filter/apple.mdx b/platform-includes/performance/traces-sampler-as-filter/apple.mdx index 9e4ca9979b6b8..ef86ac9c2d403 100644 --- a/platform-includes/performance/traces-sampler-as-filter/apple.mdx +++ b/platform-includes/performance/traces-sampler-as-filter/apple.mdx @@ -31,3 +31,20 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions * options) { + options.tracesSampler = ^NSNumber * _Nullable(SentryObjCSamplingContext * _Nonnull samplingContext) { + if (/* make a decision based on `samplingContext` */) { + // Drop this transaction, by setting its sample rate to 0% + return @0; + } else if (/* ... */) { + // Override sample rate for other cases (replaces `options.tracesSampleRate`) + return @0.1; + } + + // Can return `nil` to fallback to the rate configured by `options.tracesSampleRate` + return nil; + }; +}]; +``` diff --git a/platform-includes/performance/traces-sampler-as-sampler/apple.mdx b/platform-includes/performance/traces-sampler-as-sampler/apple.mdx index 55fa0388c8bcd..dda86d964ddbd 100644 --- a/platform-includes/performance/traces-sampler-as-sampler/apple.mdx +++ b/platform-includes/performance/traces-sampler-as-sampler/apple.mdx @@ -67,3 +67,37 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions * _Nonnull options) { + options.dsn = @"___PUBLIC_DSN___"; + + // To set a uniform sample rate + options.tracesSampleRate = @1.0; + + options.tracesSampler = ^NSNumber * _Nullable(SentryObjCSamplingContext * _Nonnull samplingContext) { + + NSString *url = samplingContext.customSamplingContext[@"url"]; + + //The desired information does not exists, do not sample. + if (url == nil) return @0.0; + + // These are important - take a big sample + if ([url isEqualToString:@"/payment"]) return @0.5; + + // Search is less important and happen much more frequently - only take 1% + if ([url isEqualToString:@"/search"]) return @0.01; + + // The health check endpoint is just noise - drop all transactions + if ([url isEqualToString:@"/health"]) return @0.0; + + // Default sample rate + return @0.01; + + // Or return nil to fallback to options.TracesSampleRate + // return nil + }; +}]; +``` diff --git a/platform-includes/scope-callback/apple.mdx b/platform-includes/scope-callback/apple.mdx index b11b0a05c0508..31180d4c0c94d 100644 --- a/platform-includes/scope-callback/apple.mdx +++ b/platform-includes/scope-callback/apple.mdx @@ -26,3 +26,19 @@ NSError *error = [NSError errorWithDomain:@"YourErrorDomain" [scope setTagValue:@"value" forKey:@"myTag"]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +NSDictionary *userInfo = @ { NSLocalizedDescriptionKey : @"Object does not exist" }; +NSError *error = [NSError errorWithDomain:@"YourErrorDomain" + code:0 + userInfo: userInfo]; + +[SentryObjCSDK captureError:error withScopeBlock:^(SentryObjCScope * _Nonnull scope) { + // Changes in here will only be captured for this event + // The scope in this callback is a clone of the current scope + // It contains all data but mutations only influence the event being sent + [scope setTagValue:@"value" forKey:@"myTag"]; +}]; +``` diff --git a/platform-includes/sensitive-data/set-tag/apple.mdx b/platform-includes/sensitive-data/set-tag/apple.mdx index 37ce0dabfb561..1b76f6916ab1c 100644 --- a/platform-includes/sensitive-data/set-tag/apple.mdx +++ b/platform-includes/sensitive-data/set-tag/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.configureScope { scope in [scope setTagValue:[YourHashTool checksumOrHash:@"08/12/1990"] forKey:@"birthday"]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope * _Nonnull scope) { + [scope setTagValue:[YourHashTool checksumOrHash:@"08/12/1990"] forKey:@"birthday"]; +}]; +``` diff --git a/platform-includes/sensitive-data/set-user/apple.mdx b/platform-includes/sensitive-data/set-user/apple.mdx index f232f5b94fe45..e3e89368fab1a 100644 --- a/platform-includes/sensitive-data/set-user/apple.mdx +++ b/platform-includes/sensitive-data/set-user/apple.mdx @@ -25,3 +25,17 @@ SentrySDK.configureScope { scope in scope.setUser(user); }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope * _Nonnull scope) { + SentryObjCUser *user = [[SentryObjCUser alloc] init]; + + // User Id: + user.userId = clientUser.id; + // Or Username: + user.username = clientUser.username; + scope.setUser(user); +}]; +``` diff --git a/platform-includes/set-environment/apple.mdx b/platform-includes/set-environment/apple.mdx index 6e68894c3cc0c..76a6f50b86348 100644 --- a/platform-includes/set-environment/apple.mdx +++ b/platform-includes/set-environment/apple.mdx @@ -15,3 +15,12 @@ SentrySDK.start { options in options.environment = @"production"; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.environment = @"production"; +}]; +``` diff --git a/platform-includes/set-extra/apple.mdx b/platform-includes/set-extra/apple.mdx index d7a4d808fc69a..0ef5844806295 100644 --- a/platform-includes/set-extra/apple.mdx +++ b/platform-includes/set-extra/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.configureScope { scope in [scope setExtraValue:@"Mighty Fighter" forKey:@"character.name"]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope * _Nonnull scope) { + [scope setExtraValue:@"Mighty Fighter" forKey:@"character.name"]; +}]; +``` diff --git a/platform-includes/set-fingerprint/basic/apple.mdx b/platform-includes/set-fingerprint/basic/apple.mdx index 6b34ad8d95911..fba764be7b69d 100644 --- a/platform-includes/set-fingerprint/basic/apple.mdx +++ b/platform-includes/set-fingerprint/basic/apple.mdx @@ -19,3 +19,14 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + event.fingerprint = @[@"my-view-function"]; + return event; + }; +}]; +``` diff --git a/platform-includes/set-fingerprint/database-connection/apple.mdx b/platform-includes/set-fingerprint/database-connection/apple.mdx index 63f9cb29637a6..264f9dc2b74ad 100644 --- a/platform-includes/set-fingerprint/database-connection/apple.mdx +++ b/platform-includes/set-fingerprint/database-connection/apple.mdx @@ -27,3 +27,17 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import +@import CoreData; + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + if ([event.error.domain isEqualToString:NSSQLiteErrorDomain]) { + event.fingerprint = @[@"database-connection-error"]; + } + return event; + }; +}]; +``` diff --git a/platform-includes/set-fingerprint/rpc/apple.mdx b/platform-includes/set-fingerprint/rpc/apple.mdx index bd076da0b3fe3..3ba44acb6c1a6 100644 --- a/platform-includes/set-fingerprint/rpc/apple.mdx +++ b/platform-includes/set-fingerprint/rpc/apple.mdx @@ -36,3 +36,23 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { + if ([event.error.domain isEqualToString:NSURLErrorDomain]) { + NSString *failingUrl = event.error.userInfo[NSURLErrorFailingURLErrorKey]; + if (failingUrl != nil) { + event.fingerprint = @[ + @"{{ default }}", + failingUrl, + @(event.error.code).stringValue + ]; + } + } + return event; + }; +}]; +``` diff --git a/platform-includes/set-level/apple.mdx b/platform-includes/set-level/apple.mdx index 24ed42ac2bb83..33f80ceca7863 100644 --- a/platform-includes/set-level/apple.mdx +++ b/platform-includes/set-level/apple.mdx @@ -13,3 +13,11 @@ SentrySDK.configureScope { scope in [scope setLevel:kSentryLevelWarning]; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK configureScope:^(SentryObjCScope * _Nonnull scope) { + [scope setLevel:SentryObjCLevelWarning]; +}]; +``` diff --git a/platform-includes/set-release/apple.mdx b/platform-includes/set-release/apple.mdx index 0fb67af0be616..c49f326888dbd 100644 --- a/platform-includes/set-release/apple.mdx +++ b/platform-includes/set-release/apple.mdx @@ -14,4 +14,12 @@ SentrySDK.start { options in }]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.releaseName = @"io.example.MyApp@1.0.0"; +}]; +``` + If no release name is set, the SDK creates a default combined from `CFBundleIdentifier`, `CFBundleShortVersionString`, and `CFBundleVersion`, for example `my.project.name@2.3.12+1234`. diff --git a/platform-includes/user-feedback/sdk-api-example/apple.mdx b/platform-includes/user-feedback/sdk-api-example/apple.mdx index 9bb85f22e4964..e06cd3210f1f6 100644 --- a/platform-includes/user-feedback/sdk-api-example/apple.mdx +++ b/platform-includes/user-feedback/sdk-api-example/apple.mdx @@ -26,11 +26,24 @@ SentryFeedback *feedback = [[SentryFeedback alloc] initWithMessage:@"It broke." [SentrySDK captureFeedback:feedback]; ``` +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +SentryObjCId *eventId = [SentryObjCSDK captureMessage:@"My message"]; + +SentryObjCFeedback *feedback = [[SentryObjCFeedback alloc] initWithMessage:@"It broke." + name:@"John Doe" + email:@"john.doe@example.com" + source:SentryFeedbackSourceCustom + associatedEventId:eventId + attachments:nil]; +[SentryObjCSDK captureFeedback:feedback]; +``` + To capture user feedback regarding a crash, use the `SentryOptions.onCrashedLastRun` callback. This callback gets called shortly after the initialization of the SDK when the last program execution terminated with a crash. It is not guaranteed that this is called on the main thread. - ```swift {tabTitle:Swift} import Sentry @@ -53,3 +66,14 @@ SentrySDK.start { options in }; }]; ``` + +```objc {tabTitle:Objective-C (SentryObjC)} +#import + +[SentryObjCSDK startWithConfigureOptions:^(SentryObjCOptions *options) { + options.dsn = @"___PUBLIC_DSN___"; + options.onCrashedLastRun = ^void(SentryObjCEvent * _Nonnull event) { + // capture user feedback + }; +}]; +```