Skip to content

Commit 5ebf15e

Browse files
feat: expose init swizzling option to ObjC consumers
Mirror enableUIViewControllerInitSwizzling in the SentryObjC wrapper, so apps using the pure Objective-C interface can enable it too. Regenerate the public API surface for the objc targets. Add this PR's number to the changelog entry, which Danger requires alongside the issue's.
1 parent 8fb37c2 commit 5ebf15e

6 files changed

Lines changed: 88 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
### Features
99

10-
- Add experimental `options.experimental.enableUIViewControllerInitSwizzling` (disabled by default) that defers `UIViewController` performance 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 could crash the app on start (#8548).
10+
- Add experimental `options.experimental.enableUIViewControllerInitSwizzling` (disabled by default) that defers `UIViewController` performance 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 could crash the app on start (#8625, #8548).
1111

1212
### Breaking Changes
1313

GH-8548-HANDOFF.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -256,22 +256,32 @@ Repo gotchas learned while wiring it up, worth knowing independently:
256256
`ERR Suite failed. error="User Abandoned Test -- User terminated"` means **timeout**, not assertion
257257
failure.
258258

259-
## Deferred (non-blocking, still open)
259+
## Ready-for-review checklist
260260

261-
1. **Changelog is missing the PR number** — Danger fails with "Please consider adding a changelog
262-
entry". The entry exists under `## Unreleased` → Features but omits `(#8625)`, which Danger
263-
requires. One-line fix.
264-
2. **ObjC mirror missing**`enableUIViewControllerInitSwizzling` is absent from
261+
Done:
262+
263+
1. **Changelog** — entry under `## Unreleased` → Features now carries `(#8625, #8548)`. Danger requires
264+
this PR's own number, not just the issue's.
265+
2. **ObjC mirror**`enableUIViewControllerInitSwizzling` added to
265266
`Sources/SentryObjC/Public/SentryObjCExperimentalOptions.h` and
266-
`Sources/SentryObjCCompat/SentryObjCExperimentalOptions.swift`, so pure-ObjC consumers can't enable
267-
the fix. Note `enableStandaloneAppStartTracing` is **also** unmirrored, so there is precedent either
268-
way; decide whether to mirror just this one, both, or neither (and document the reason).
267+
`Sources/SentryObjCCompat/SentryObjCExperimentalOptions.swift`, so pure-ObjC consumers can enable
268+
it. `sdk_api*.json` regenerated, including the `objc` and `objccompat` surfaces.
269+
(`enableStandaloneAppStartTracing` remains unmirrored — pre-existing, out of scope here.)
269270
3. **`run-full-ci` label** — applied.
270-
4. **Delete this handoff file before merge** — it is agent scratch, not maintainer docs. The durable
271-
content lives in the PR description and code comments.
272-
Also close (don't merge) **PR #8667**, the stacked iOS 15 probe.
271+
4. **Public API surface** — regenerated via `make generate-public-api`; the `api-stability` check
272+
diffs it against the committed files.
273+
274+
Still open:
275+
273276
5. **Don't close #8548 with this PR** — the option defaults to **off**, so default-configuration users
274277
remain exposed. Reference the issue; close it when the default flips.
278+
6. **Delete this handoff file before merge** — it is agent scratch, not maintainer docs. The durable
279+
content lives in the PR description and code comments. Keeping it for now, on request.
280+
Also close (don't merge) **PR #8667**, the stacked iOS 15 probe.
281+
7. **Known-flaky CI, not caused by this PR**`Collect App Metrics` and the `Release` gate that
282+
depends on it failed with SauceLabs session errors (`Unable to find session with requested ID`,
283+
WebDriverAgent session drops) on the perf-test apps, which this PR doesn't touch. Every substantive
284+
job in that run passed. Worth one re-run once SauceLabs is less congested.
275285

276286
## How to pick this up
277287

Sources/SentryObjC/Public/SentryObjCExperimentalOptions.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,27 @@ NS_ASSUME_NONNULL_BEGIN
2121
/// When enabled, the SDK uses a more efficient mechanism for detecting watchdog terminations.
2222
@property (nonatomic) BOOL enableWatchdogTerminationsV2;
2323

24+
/**
25+
* Reduces SDK start overhead by swizzling each @c UIViewController subclass lazily, the first time
26+
* an instance of it is created, instead of eagerly discovering and swizzling every subclass when
27+
* the SDK starts.
28+
*
29+
* By default, the SDK scans loaded binary images for all @c UIViewController subclasses at start
30+
* and swizzles them up front. This realizes every subclass to inspect it, so the cost grows with
31+
* the number of view controllers in the app - including ones it never uses - and it realizes
32+
* @c \@available -gated subclasses that reference newer-framework types, which crashes on OS
33+
* versions below the gate.
34+
*
35+
* With this option, only classes the app actually instantiates are touched: a class that can't
36+
* exist on the current OS is never instantiated, so it's never realized or swizzled. This cuts
37+
* start-up work and avoids the gated-subclass crash while producing the same @c ui.load
38+
* auto-instrumentation transactions.
39+
*
40+
* @warning This is an experimental feature and is therefore disabled by default.
41+
* @see https://github.com/getsentry/sentry-cocoa/issues/8548
42+
*/
43+
@property (nonatomic) BOOL enableUIViewControllerInitSwizzling;
44+
2445
/// Initializes experimental options with default values.
2546
- (instancetype)init;
2647

Sources/SentryObjCCompat/SentryObjCExperimentalOptions.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ import Foundation
2626
get { wrapped.enableWatchdogTerminationsV2 }
2727
set { wrapped.enableWatchdogTerminationsV2 = newValue }
2828
}
29+
30+
@objc public var enableUIViewControllerInitSwizzling: Bool {
31+
get { wrapped.enableUIViewControllerInitSwizzling }
32+
set { wrapped.enableUIViewControllerInitSwizzling = newValue }
33+
}
2934
}
3035

3136
// swiftlint:enable missing_docs

sdk_api_objc.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,13 @@
20892089
"returnType": "BOOL",
20902090
"instance": true
20912091
},
2092+
{
2093+
"kind": "ObjCMethodDecl",
2094+
"name": "enableUIViewControllerInitSwizzling",
2095+
"parent": "SentryObjCExperimentalOptions",
2096+
"returnType": "BOOL",
2097+
"instance": true
2098+
},
20922099
{
20932100
"kind": "ObjCMethodDecl",
20942101
"name": "enableUIViewControllerTracing",
@@ -5883,6 +5890,13 @@
58835890
"returnType": "void",
58845891
"instance": true
58855892
},
5893+
{
5894+
"kind": "ObjCMethodDecl",
5895+
"name": "setEnableUIViewControllerInitSwizzling:",
5896+
"parent": "SentryObjCExperimentalOptions",
5897+
"returnType": "void",
5898+
"instance": true
5899+
},
58865900
{
58875901
"kind": "ObjCMethodDecl",
58885902
"name": "setEnableUIViewControllerTracing:",
@@ -9126,6 +9140,12 @@
91269140
"parent": "SentryObjCOptions",
91279141
"type": "BOOL"
91289142
},
9143+
{
9144+
"kind": "ObjCPropertyDecl",
9145+
"name": "enableUIViewControllerInitSwizzling",
9146+
"parent": "SentryObjCExperimentalOptions",
9147+
"type": "BOOL"
9148+
},
91299149
{
91309150
"kind": "ObjCPropertyDecl",
91319151
"name": "enableUIViewControllerTracing",

sdk_api_objc_v10.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,6 +2202,13 @@
22022202
"returnType": "BOOL",
22032203
"instance": true
22042204
},
2205+
{
2206+
"kind": "ObjCMethodDecl",
2207+
"name": "enableUIViewControllerInitSwizzling",
2208+
"parent": "SentryObjCExperimentalOptions",
2209+
"returnType": "BOOL",
2210+
"instance": true
2211+
},
22052212
{
22062213
"kind": "ObjCMethodDecl",
22072214
"name": "enableUIViewControllerTracing",
@@ -6115,6 +6122,13 @@
61156122
"returnType": "void",
61166123
"instance": true
61176124
},
6125+
{
6126+
"kind": "ObjCMethodDecl",
6127+
"name": "setEnableUIViewControllerInitSwizzling:",
6128+
"parent": "SentryObjCExperimentalOptions",
6129+
"returnType": "void",
6130+
"instance": true
6131+
},
61186132
{
61196133
"kind": "ObjCMethodDecl",
61206134
"name": "setEnableUIViewControllerTracing:",
@@ -9468,6 +9482,12 @@
94689482
"parent": "SentryObjCOptions",
94699483
"type": "BOOL"
94709484
},
9485+
{
9486+
"kind": "ObjCPropertyDecl",
9487+
"name": "enableUIViewControllerInitSwizzling",
9488+
"parent": "SentryObjCExperimentalOptions",
9489+
"type": "BOOL"
9490+
},
94719491
{
94729492
"kind": "ObjCPropertyDecl",
94739493
"name": "enableUIViewControllerTracing",

0 commit comments

Comments
 (0)