From a43c96dd3ad59be65ef8e79369398ad07011f833 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Thu, 6 Aug 2026 16:37:51 -0300 Subject: [PATCH 1/3] feat: promote standalone app start out of experimental Move `enableStandaloneAppStartTracing` from `options.experimental` to a top-level option on `Options`. --- CHANGELOG.md | 1 + .../SentrySampleShared/SentrySDKWrapper.swift | 2 +- Sources/SentryObjC/Public/SentryObjCOptions.h | 7 +++++++ Sources/SentryObjCCompat/SentryObjCOptions.swift | 5 +++++ Sources/Swift/Helper/SentryEnabledFeaturesBuilder.swift | 2 +- Sources/Swift/Helper/SentrySDK.swift | 2 +- Sources/Swift/Options.swift | 6 ++++++ Sources/Swift/SentryDependencyContainer.swift | 2 +- Sources/Swift/SentryExperimentalOptions.swift | 6 ------ .../Helper/SentryEnabledFeaturesBuilderTests.swift | 4 ++-- 10 files changed, 25 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 840c8655a3..5e9ff06ce0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Features +- Promote `enableStandaloneAppStartTracing` from `options.experimental` to a top-level option on `Options` (#TBD) - Add experimental option `enableUIViewControllerInitSwizzling` that defers `UIViewController` swizzling to first instantiation instead of eagerly discovering and swizzling all subclasses at SDK start. This avoids realizing `@available`-gated `UIViewController` subclasses on OS versions below their gate, which crashes apps on start (#8687). ### Fixes diff --git a/Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift b/Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift index 12972b760e..a650603676 100644 --- a/Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift +++ b/Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift @@ -201,7 +201,7 @@ public struct SentrySDKWrapper { options.enableUserInteractionTracing = !isBenchmarking && !SentrySDKOverrides.UIEventTracking.disableTracing.boolValue options.enablePreWarmedAppStartTracing = !isBenchmarking && !SentrySDKOverrides.AppStart.disablePrewarmedTracing.boolValue - options.experimental.enableStandaloneAppStartTracing = SentrySDKOverrides.AppStart.enableStandaloneTracing.boolValue + options.enableStandaloneAppStartTracing = SentrySDKOverrides.AppStart.enableStandaloneTracing.boolValue options.enableUIViewControllerTracing = !SentrySDKOverrides.UIViewControllerTracing.disable.boolValue options.experimental.enableUIViewControllerInitSwizzling = SentrySDKOverrides.UIViewControllerTracing.enableInitSwizzling.boolValue diff --git a/Sources/SentryObjC/Public/SentryObjCOptions.h b/Sources/SentryObjC/Public/SentryObjCOptions.h index d7bbdf126d..8dbb9720d2 100644 --- a/Sources/SentryObjC/Public/SentryObjCOptions.h +++ b/Sources/SentryObjC/Public/SentryObjCOptions.h @@ -572,6 +572,13 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic) BOOL enablePreWarmedAppStartTracing; +/** + * When enabled, the SDK sends a standalone app start transaction instead of attaching app + * start data to the first UIViewController transaction. + * @note Default value is @c NO. + */ +@property (nonatomic) BOOL enableStandaloneAppStartTracing; + /** * When enabled, the SDK reports non-fully-blocking app hangs. A non-fully-blocking app hang is * when the app appears stuck to the user but can still render a few frames. diff --git a/Sources/SentryObjCCompat/SentryObjCOptions.swift b/Sources/SentryObjCCompat/SentryObjCOptions.swift index 4dc3cb0840..b05b5da954 100644 --- a/Sources/SentryObjCCompat/SentryObjCOptions.swift +++ b/Sources/SentryObjCCompat/SentryObjCOptions.swift @@ -344,6 +344,11 @@ import Foundation set { wrapped.enablePreWarmedAppStartTracing = newValue } } + @objc public var enableStandaloneAppStartTracing: Bool { + get { wrapped.enableStandaloneAppStartTracing } + set { wrapped.enableStandaloneAppStartTracing = newValue } + } + @objc public var enableReportNonFullyBlockingAppHangs: Bool { get { wrapped.enableReportNonFullyBlockingAppHangs } set { wrapped.enableReportNonFullyBlockingAppHangs = newValue } diff --git a/Sources/Swift/Helper/SentryEnabledFeaturesBuilder.swift b/Sources/Swift/Helper/SentryEnabledFeaturesBuilder.swift index 0cf53ec93a..d12c240cf5 100644 --- a/Sources/Swift/Helper/SentryEnabledFeaturesBuilder.swift +++ b/Sources/Swift/Helper/SentryEnabledFeaturesBuilder.swift @@ -52,7 +52,7 @@ import Foundation if options.enableMetrics { features.append("metrics") } - if options.experimental.enableStandaloneAppStartTracing { + if options.enableStandaloneAppStartTracing { features.append("standaloneAppStartTracing") } if options.experimental.enableWatchdogTerminationsV2 { diff --git a/Sources/Swift/Helper/SentrySDK.swift b/Sources/Swift/Helper/SentrySDK.swift index bf8db6e758..0c8ab59cc3 100644 --- a/Sources/Swift/Helper/SentrySDK.swift +++ b/Sources/Swift/Helper/SentrySDK.swift @@ -582,7 +582,7 @@ extension SentrySDK { /// func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { /// SentrySDK.start(configureOptions: { options in /// ... - /// options.experimental.enableStandaloneAppStartTracing = true + /// options.enableStandaloneAppStartTracing = true /// }) /// SentrySDK.extendAppStart() /// diff --git a/Sources/Swift/Options.swift b/Sources/Swift/Options.swift index 07669171d8..4156f89945 100644 --- a/Sources/Swift/Options.swift +++ b/Sources/Swift/Options.swift @@ -345,6 +345,12 @@ /// @note Default value is @c true. @objc public var enablePreWarmedAppStartTracing: Bool = true + /// When enabled, the SDK sends a standalone app start transaction instead of attaching app + /// start data to the first UIViewController transaction. + /// + /// @note Default value is @c false. + @objc public var enableStandaloneAppStartTracing: Bool = false + /// When enabled the SDK reports non-fully-blocking app hangs. A non-fully-blocking app hang is when /// the app appears stuck to the user but can still render a few frames. /// diff --git a/Sources/Swift/SentryDependencyContainer.swift b/Sources/Swift/SentryDependencyContainer.swift index 13bc0018e8..a9a08f0cde 100644 --- a/Sources/Swift/SentryDependencyContainer.swift +++ b/Sources/Swift/SentryDependencyContainer.swift @@ -324,7 +324,7 @@ extension SentryFileManager: SentryFileManagerProtocol { } appStateManager: appStateManager, framesTracker: framesTracker, enablePreWarmedAppStartTracing: options.enablePreWarmedAppStartTracing, - enableStandaloneAppStartTracing: options.experimental.enableStandaloneAppStartTracing, + enableStandaloneAppStartTracing: options.enableStandaloneAppStartTracing, dateProvider: dateProvider, sysctlWrapper: sysctlWrapper, appStartInfoProvider: appStartInfoProvider, diff --git a/Sources/Swift/SentryExperimentalOptions.swift b/Sources/Swift/SentryExperimentalOptions.swift index be887b39c9..8db0a17769 100644 --- a/Sources/Swift/SentryExperimentalOptions.swift +++ b/Sources/Swift/SentryExperimentalOptions.swift @@ -16,12 +16,6 @@ public final class SentryExperimentalOptions: NSObject { /// When enabled, the SDK uses a more efficient mechanism for detecting watchdog terminations. public var enableWatchdogTerminationsV2 = false - /** - * When enabled, the SDK sends a standalone app start transaction instead of attaching app - * start data to the first UIViewController transaction. - */ - public var enableStandaloneAppStartTracing = false - /** * Reduces SDK start overhead by swizzling each `UIViewController` subclass lazily, the first * time an instance of it is created, instead of eagerly discovering and swizzling every diff --git a/Tests/SentryTests/Helper/SentryEnabledFeaturesBuilderTests.swift b/Tests/SentryTests/Helper/SentryEnabledFeaturesBuilderTests.swift index 5fb661a474..acd06588b8 100644 --- a/Tests/SentryTests/Helper/SentryEnabledFeaturesBuilderTests.swift +++ b/Tests/SentryTests/Helper/SentryEnabledFeaturesBuilderTests.swift @@ -308,7 +308,7 @@ final class SentryEnabledFeaturesBuilderTests: XCTestCase { func testEnableStandaloneAppStartTracing_isEnabled_shouldAddFeature() throws { // -- Arrange -- let options = Options() - options.experimental.enableStandaloneAppStartTracing = true + options.enableStandaloneAppStartTracing = true // -- Act -- let features = SentryEnabledFeaturesBuilder.getEnabledFeatures(options: options) @@ -320,7 +320,7 @@ final class SentryEnabledFeaturesBuilderTests: XCTestCase { func testEnableStandaloneAppStartTracing_isDisabled_shouldNotAddFeature() throws { // -- Arrange -- let options = Options() - options.experimental.enableStandaloneAppStartTracing = false + options.enableStandaloneAppStartTracing = false // -- Act -- let features = SentryEnabledFeaturesBuilder.getEnabledFeatures(options: options) From f78a65e215e312ffaf59073685b3076ccceeefae Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Thu, 6 Aug 2026 16:38:33 -0300 Subject: [PATCH 2/3] chore: update changelog with PR number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e9ff06ce0..3d26e60eb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- Promote `enableStandaloneAppStartTracing` from `options.experimental` to a top-level option on `Options` (#TBD) +- Promote `enableStandaloneAppStartTracing` from `options.experimental` to a top-level option on `Options` (#8715) - Add experimental option `enableUIViewControllerInitSwizzling` that defers `UIViewController` swizzling to first instantiation instead of eagerly discovering and swizzling all subclasses at SDK start. This avoids realizing `@available`-gated `UIViewController` subclasses on OS versions below their gate, which crashes apps on start (#8687). ### Fixes From bb60248ea6bec97a405be80667d7c92a5c3666fa Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Thu, 6 Aug 2026 16:53:43 -0300 Subject: [PATCH 3/3] Run generate api --- sdk_api.json | 152 +++++++++++++++++++++--------------------- sdk_api_objc.json | 20 ++++++ sdk_api_objc_v10.json | 20 ++++++ sdk_api_v10.json | 152 +++++++++++++++++++++--------------------- 4 files changed, 192 insertions(+), 152 deletions(-) diff --git a/sdk_api.json b/sdk_api.json index bca2b1e670..020129104e 100644 --- a/sdk_api.json +++ b/sdk_api.json @@ -24380,6 +24380,82 @@ "printedName": "enableSpotlight", "usr": "c:@M@Sentry@objc(cs)SentryOptions(py)enableSpotlight" }, + { + "accessors": [ + { + "accessorKind": "get", + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + } + ], + "declAttributes": [ + "Final", + "ObjC" + ], + "declKind": "Accessor", + "implicit": true, + "kind": "Accessor", + "mangledName": "$s6Sentry7OptionsC31enableStandaloneAppStartTracingSbvg", + "moduleName": "Sentry", + "name": "Get", + "printedName": "Get()", + "usr": "c:@M@Sentry@objc(cs)SentryOptions(im)enableStandaloneAppStartTracing" + }, + { + "accessorKind": "set", + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + }, + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ], + "declAttributes": [ + "Final", + "ObjC" + ], + "declKind": "Accessor", + "implicit": true, + "kind": "Accessor", + "mangledName": "$s6Sentry7OptionsC31enableStandaloneAppStartTracingSbvs", + "moduleName": "Sentry", + "name": "Set", + "printedName": "Set()", + "usr": "c:@M@Sentry@objc(cs)SentryOptions(im)setEnableStandaloneAppStartTracing:" + } + ], + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + } + ], + "declAttributes": [ + "Final", + "HasStorage", + "ObjC" + ], + "declKind": "Var", + "hasStorage": true, + "kind": "Var", + "mangledName": "$s6Sentry7OptionsC31enableStandaloneAppStartTracingSbvp", + "moduleName": "Sentry", + "name": "enableStandaloneAppStartTracing", + "printedName": "enableStandaloneAppStartTracing", + "usr": "c:@M@Sentry@objc(cs)SentryOptions(py)enableStandaloneAppStartTracing" + }, { "accessors": [ { @@ -38652,82 +38728,6 @@ "printedName": "init()", "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(im)init" }, - { - "accessors": [ - { - "accessorKind": "get", - "children": [ - { - "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - } - ], - "declAttributes": [ - "Final", - "ObjC" - ], - "declKind": "Accessor", - "implicit": true, - "kind": "Accessor", - "mangledName": "$s6Sentry0A19ExperimentalOptionsC31enableStandaloneAppStartTracingSbvg", - "moduleName": "Sentry", - "name": "Get", - "printedName": "Get()", - "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(im)enableStandaloneAppStartTracing" - }, - { - "accessorKind": "set", - "children": [ - { - "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - }, - { - "kind": "TypeNominal", - "name": "Void", - "printedName": "()" - } - ], - "declAttributes": [ - "Final", - "ObjC" - ], - "declKind": "Accessor", - "implicit": true, - "kind": "Accessor", - "mangledName": "$s6Sentry0A19ExperimentalOptionsC31enableStandaloneAppStartTracingSbvs", - "moduleName": "Sentry", - "name": "Set", - "printedName": "Set()", - "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(im)setEnableStandaloneAppStartTracing:" - } - ], - "children": [ - { - "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - } - ], - "declAttributes": [ - "Final", - "HasStorage", - "ObjC" - ], - "declKind": "Var", - "hasStorage": true, - "kind": "Var", - "mangledName": "$s6Sentry0A19ExperimentalOptionsC31enableStandaloneAppStartTracingSbvp", - "moduleName": "Sentry", - "name": "enableStandaloneAppStartTracing", - "printedName": "enableStandaloneAppStartTracing", - "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(py)enableStandaloneAppStartTracing" - }, { "accessors": [ { diff --git a/sdk_api_objc.json b/sdk_api_objc.json index 142b71193b..efe4be5002 100644 --- a/sdk_api_objc.json +++ b/sdk_api_objc.json @@ -2075,6 +2075,13 @@ "returnType": "BOOL", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "enableStandaloneAppStartTracing", + "parent": "SentryObjCOptions", + "returnType": "BOOL", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "enableSwizzling", @@ -5876,6 +5883,13 @@ "returnType": "void", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "setEnableStandaloneAppStartTracing:", + "parent": "SentryObjCOptions", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "setEnableSwizzling:", @@ -9128,6 +9142,12 @@ "parent": "SentryObjCOptions", "type": "BOOL" }, + { + "kind": "ObjCPropertyDecl", + "name": "enableStandaloneAppStartTracing", + "parent": "SentryObjCOptions", + "type": "BOOL" + }, { "kind": "ObjCPropertyDecl", "name": "enableSwizzling", diff --git a/sdk_api_objc_v10.json b/sdk_api_objc_v10.json index 2e0c24824d..ffe5e1eb76 100644 --- a/sdk_api_objc_v10.json +++ b/sdk_api_objc_v10.json @@ -2162,6 +2162,13 @@ "returnType": "BOOL", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "enableStandaloneAppStartTracing", + "parent": "SentryObjCOptions", + "returnType": "BOOL", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "enableSwizzling", @@ -6026,6 +6033,13 @@ "returnType": "void", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "setEnableStandaloneAppStartTracing:", + "parent": "SentryObjCOptions", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "setEnableSwizzling:", @@ -9320,6 +9334,12 @@ "parent": "SentryObjCOptions", "type": "BOOL" }, + { + "kind": "ObjCPropertyDecl", + "name": "enableStandaloneAppStartTracing", + "parent": "SentryObjCOptions", + "type": "BOOL" + }, { "kind": "ObjCPropertyDecl", "name": "enableSwizzling", diff --git a/sdk_api_v10.json b/sdk_api_v10.json index 3741e1550f..68ff5fe89f 100644 --- a/sdk_api_v10.json +++ b/sdk_api_v10.json @@ -24453,6 +24453,82 @@ "printedName": "enableSpotlight", "usr": "c:@M@Sentry@objc(cs)SentryOptions(py)enableSpotlight" }, + { + "accessors": [ + { + "accessorKind": "get", + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + } + ], + "declAttributes": [ + "Final", + "ObjC" + ], + "declKind": "Accessor", + "implicit": true, + "kind": "Accessor", + "mangledName": "$s6Sentry7OptionsC31enableStandaloneAppStartTracingSbvg", + "moduleName": "Sentry", + "name": "Get", + "printedName": "Get()", + "usr": "c:@M@Sentry@objc(cs)SentryOptions(im)enableStandaloneAppStartTracing" + }, + { + "accessorKind": "set", + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + }, + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ], + "declAttributes": [ + "Final", + "ObjC" + ], + "declKind": "Accessor", + "implicit": true, + "kind": "Accessor", + "mangledName": "$s6Sentry7OptionsC31enableStandaloneAppStartTracingSbvs", + "moduleName": "Sentry", + "name": "Set", + "printedName": "Set()", + "usr": "c:@M@Sentry@objc(cs)SentryOptions(im)setEnableStandaloneAppStartTracing:" + } + ], + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + } + ], + "declAttributes": [ + "Final", + "HasStorage", + "ObjC" + ], + "declKind": "Var", + "hasStorage": true, + "kind": "Var", + "mangledName": "$s6Sentry7OptionsC31enableStandaloneAppStartTracingSbvp", + "moduleName": "Sentry", + "name": "enableStandaloneAppStartTracing", + "printedName": "enableStandaloneAppStartTracing", + "usr": "c:@M@Sentry@objc(cs)SentryOptions(py)enableStandaloneAppStartTracing" + }, { "accessors": [ { @@ -39983,82 +40059,6 @@ "printedName": "init()", "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(im)init" }, - { - "accessors": [ - { - "accessorKind": "get", - "children": [ - { - "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - } - ], - "declAttributes": [ - "Final", - "ObjC" - ], - "declKind": "Accessor", - "implicit": true, - "kind": "Accessor", - "mangledName": "$s6Sentry0A19ExperimentalOptionsC31enableStandaloneAppStartTracingSbvg", - "moduleName": "Sentry", - "name": "Get", - "printedName": "Get()", - "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(im)enableStandaloneAppStartTracing" - }, - { - "accessorKind": "set", - "children": [ - { - "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - }, - { - "kind": "TypeNominal", - "name": "Void", - "printedName": "()" - } - ], - "declAttributes": [ - "Final", - "ObjC" - ], - "declKind": "Accessor", - "implicit": true, - "kind": "Accessor", - "mangledName": "$s6Sentry0A19ExperimentalOptionsC31enableStandaloneAppStartTracingSbvs", - "moduleName": "Sentry", - "name": "Set", - "printedName": "Set()", - "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(im)setEnableStandaloneAppStartTracing:" - } - ], - "children": [ - { - "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - } - ], - "declAttributes": [ - "Final", - "HasStorage", - "ObjC" - ], - "declKind": "Var", - "hasStorage": true, - "kind": "Var", - "mangledName": "$s6Sentry0A19ExperimentalOptionsC31enableStandaloneAppStartTracingSbvp", - "moduleName": "Sentry", - "name": "enableStandaloneAppStartTracing", - "printedName": "enableStandaloneAppStartTracing", - "usr": "c:@M@Sentry@objc(cs)SentryExperimentalOptions(py)enableStandaloneAppStartTracing" - }, { "accessors": [ {