From 5044d0a13fc17d2e51c60fb5ad98379c406bda0d Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 29 Jul 2026 15:25:51 +0200 Subject: [PATCH 1/6] feat: Runtime toggle for shake-to-report feedback Add SentrySDK.feedback.setShakeGestureEnabled(_:) to enable or disable the shake-to-report user feedback trigger at runtime, after SentrySDK.start. Sentry's options are applied synchronously during start, so consumers that decide whether to offer feedback based on an asynchronously resolved signal (e.g. a feature flag or a user role fetched at launch) could not express that choice through the useShakeGesture option alone. This routes the toggle through the feedback integration driver, which manages both the shake detector state and its notification observer, so enabling after init with useShakeGesture=false also registers the observer. The new API is exposed on the SentryObjC wrapper and is callable from hybrid SDKs via the main SDK's ObjC interface. --- CHANGELOG.md | 1 + .../SentryObjC/Public/SentryObjCFeedbackApi.h | 12 ++ .../SentryObjCFeedbackApi.swift | 5 + .../UserFeedback/SentryFeedbackAPI.swift | 21 +++ .../SentryUserFeedbackIntegrationDriver.swift | 25 ++- .../SentryObjCFeedbackApiTests.m | 7 + .../UserFeedbackIntegrationTests.swift | 166 ++++++++++++++++++ sdk_api.json | 28 +++ sdk_api_objc.json | 7 + sdk_api_objc_v10.json | 7 + sdk_api_v10.json | 28 +++ 11 files changed, 305 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b27098e056..933a264c8b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Add `Breadcrumb.setData(value:key:)` to set a single breadcrumb data entry and deprecate the `Breadcrumb.data` setter in its favor. (#8572) +- Add `SentrySDK.feedback.setShakeGestureEnabled(_:)` to toggle the shake-to-report gesture at runtime (#7970) ### Fixes diff --git a/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h b/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h index 228371f74e7..9d531f9f907 100644 --- a/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h +++ b/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h @@ -61,6 +61,18 @@ SENTRY_NO_INIT SentryObjCUserFeedbackConfiguration *configuration))configure NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); +/** + * Enables or disables the shake-gesture trigger for the feedback form at runtime. + * @discussion Use this to toggle shake-to-report after @c SentrySDK.start, e.g. once an + * asynchronously fetched feature flag resolves. Requires the User Feedback integration to be + * configured; otherwise this is a no-op. + * @param enabled @c YES to start presenting the feedback form on shake; @c NO to stop. + * @note This method must be called from the main thread. + * @warning This is an experimental feature and may still have bugs. + */ +- (void)setShakeGestureEnabled:(BOOL)enabled + NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); + # if !SDK_V10 /** * Show the feedback widget button. diff --git a/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift b/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift index 79255cba463..83ef0afa8a6 100644 --- a/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift +++ b/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift @@ -39,6 +39,11 @@ import UIKit wrapped.show(screenshot: screenshot, configure: wrappedConfigure(configure)) } + @available(iOSApplicationExtension, unavailable) + @objc public func setShakeGestureEnabled(_ enabled: Bool) { + wrapped.setShakeGestureEnabled(enabled) + } + #if !SDK_V10 @available(iOSApplicationExtension, unavailable) @available(*, deprecated, message: "The Sentry-managed User Feedback widget is deprecated and will be removed in v10.") diff --git a/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift b/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift index c0971cf082a..69573bc9912 100644 --- a/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift +++ b/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift @@ -61,6 +61,27 @@ import UIKit driver.showForm(from: presenter, screenshot: screenshot, configure: configure) } + /// Enables or disables the shake-gesture trigger for the feedback form at runtime. + /// + /// Sentry's options are applied synchronously during `SentrySDK.start`, so consumers that + /// decide whether to offer feedback based on an asynchronous signal (e.g. a feature flag or a + /// user role fetched at launch) cannot express that choice through `useShakeGesture` alone. + /// Use this method to toggle shake-to-report after initialization. + /// + /// Requires the User Feedback integration to be configured (`SentryOptions.configureUserFeedback`); + /// otherwise this is a no-op. Only affects iOS/iPadOS; a no-op on other platforms. + /// - Parameter enabled: `true` to start presenting the feedback form on shake; `false` to stop. + /// - Important: Call this method from the main thread. + /// - warning: This is an experimental feature and may still have bugs. + @available(iOSApplicationExtension, unavailable) + @objc public func setShakeGestureEnabled(_ enabled: Bool) { + guard let driver = getIntegration()?.driver else { + SentrySDKLog.debug("Cannot toggle shake gesture — user feedback is not configured") + return + } + driver.setShakeGestureEnabled(enabled) + } + @available(iOSApplicationExtension, unavailable) private func getIntegration() -> UserFeedbackIntegration? { SentrySDKInternal.currentHub().getInstalledIntegration(UserFeedbackIntegration.self) as? UserFeedbackIntegration diff --git a/Sources/Swift/Integrations/UserFeedback/SentryUserFeedbackIntegrationDriver.swift b/Sources/Swift/Integrations/UserFeedback/SentryUserFeedbackIntegrationDriver.swift index b9b06dfbf23..d13d037db8a 100644 --- a/Sources/Swift/Integrations/UserFeedback/SentryUserFeedbackIntegrationDriver.swift +++ b/Sources/Swift/Integrations/UserFeedback/SentryUserFeedbackIntegrationDriver.swift @@ -12,6 +12,7 @@ import UIKit final class SentryUserFeedbackIntegrationDriver: NSObject { let configuration: SentryUserFeedbackConfiguration private weak var activeForm: SentryUserFeedbackFormController? + private var isObservingShakeGesture = false let screenshotSource: SentryScreenshotSource let windowFactory: SentryUserFeedbackWindowFactory private let notificationCenter: SentryNSNotificationCenterWrapper @@ -163,6 +164,27 @@ extension SentryUserFeedbackIntegrationDriver { activeForm = form presenter.present(form, animated: formConfig.animations) } + + /// Enables or disables shake-gesture-triggered feedback at runtime. + /// + /// This lets consumers toggle shake-to-report after `SentrySDK.start`, e.g. once an + /// asynchronously fetched feature flag resolves. Repeated calls with the same value are no-ops. + /// - Parameter enabled: `true` to start detecting shakes and presenting the feedback form; + /// `false` to stop. + func setShakeGestureEnabled(_ enabled: Bool) { + configuration.useShakeGesture = enabled + if enabled { + guard !isObservingShakeGesture else { return } + isObservingShakeGesture = true + SentryShakeDetector.enable() + notificationCenter.addObserver(self, selector: #selector(handleShakeGesture), name: .SentryShakeDetected, object: nil) + } else { + guard isObservingShakeGesture else { return } + isObservingShakeGesture = false + SentryShakeDetector.disable() + notificationCenter.removeObserver(self, name: .SentryShakeDetected, object: nil) + } + } } // MARK: Private @@ -209,8 +231,7 @@ private extension SentryUserFeedbackIntegrationDriver { SentrySDKLog.debug("Shake gesture detection is disabled in configuration") return } - SentryShakeDetector.enable() - notificationCenter.addObserver(self, selector: #selector(handleShakeGesture), name: .SentryShakeDetected, object: nil) + setShakeGestureEnabled(true) } @objc func handleShakeGesture() { diff --git a/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m b/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m index 1bdcc89f6d4..f7b6c76c4f1 100644 --- a/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m +++ b/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m @@ -40,6 +40,13 @@ - (void)testShowWithScreenshotAndConfigure_whenNoPresenter_shouldNotCrash }]; } +- (void)testSetShakeGestureEnabled_whenFeedbackNotConfigured_shouldNotCrash +{ + // -- Act & Assert (no crash) -- + [SentryObjCSDK.feedback setShakeGestureEnabled:YES]; + [SentryObjCSDK.feedback setShakeGestureEnabled:NO]; +} + @end #endif diff --git a/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift b/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift index 3256e5cb12a..cc48cdb61de 100644 --- a/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift @@ -355,6 +355,172 @@ final class UserFeedbackIntegrationTests: XCTestCase { withExtendedLifetime(window) { } } + func testSetShakeGestureEnabled_whenEnabledAtRuntime_shouldPresentFormOnShake() throws { + let window = makeWindow() + let viewController = TestPresentingViewController() + let config = SentryUserFeedbackConfiguration() + config.animations = false + config.useShakeGesture = false + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource()) + useFallbackPresenter(viewController, in: window) + + // Not observing yet — a shake should be ignored. + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + XCTAssertFalse(sut.displayingForm) + + sut.setShakeGestureEnabled(true) + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + + _ = try XCTUnwrap(viewController.lastPresentedViewController as? SentryUserFeedbackFormController) + XCTAssertTrue(sut.displayingForm) + XCTAssertTrue(config.useShakeGesture) + + withExtendedLifetime(window) { } + } + + func testSetShakeGestureEnabled_whenDisabledAtRuntime_shouldNotPresentFormOnShake() { + let window = makeWindow() + let viewController = TestPresentingViewController() + let config = SentryUserFeedbackConfiguration() + config.animations = false + config.useShakeGesture = true + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource()) + useFallbackPresenter(viewController, in: window) + + sut.setShakeGestureEnabled(false) + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + + XCTAssertFalse(sut.displayingForm) + XCTAssertEqual(viewController.presentCallCount, 0) + XCTAssertFalse(config.useShakeGesture) + + withExtendedLifetime(window) { } + } + + func testSetShakeGestureEnabled_whenEnabledTwice_shouldRegisterObserverOnce() { + let notificationCenter = TestNSNotificationCenterWrapper() + let config = SentryUserFeedbackConfiguration() + config.useShakeGesture = false + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource(), + notificationCenter: notificationCenter) + + sut.setShakeGestureEnabled(true) + sut.setShakeGestureEnabled(true) + + let shakeObservers = notificationCenter.addObserverWithObjectInvocations.invocations + .filter { $0.name == .SentryShakeDetected } + XCTAssertEqual(shakeObservers.count, 1) + } + + func testSetShakeGestureEnabled_whenDisabledAfterInit_shouldRemoveObserver() throws { + let notificationCenter = TestNSNotificationCenterWrapper() + let config = SentryUserFeedbackConfiguration() + config.useShakeGesture = true + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource(), + notificationCenter: notificationCenter) + + sut.setShakeGestureEnabled(false) + + let removal = try XCTUnwrap(notificationCenter.removeObserverWithNameAndObjectInvocations + .invocations.first { $0.name == .SentryShakeDetected }) + XCTAssertEqual(removal.name, .SentryShakeDetected) + } + + func testSetShakeGestureEnabled_whenReEnabledAfterDisable_shouldPresentFormOnShake() throws { + let window = makeWindow() + let viewController = TestPresentingViewController() + let config = SentryUserFeedbackConfiguration() + config.animations = false + config.useShakeGesture = true + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource()) + useFallbackPresenter(viewController, in: window) + + sut.setShakeGestureEnabled(false) + sut.setShakeGestureEnabled(true) + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + + _ = try XCTUnwrap(viewController.lastPresentedViewController as? SentryUserFeedbackFormController) + XCTAssertTrue(sut.displayingForm) + XCTAssertTrue(config.useShakeGesture) + + withExtendedLifetime(window) { } + } + + func testSetShakeGestureEnabled_whenDisabled_shouldKeepScreenshotObserver() throws { + let notificationCenter = TestNSNotificationCenterWrapper() + let config = SentryUserFeedbackConfiguration() + config.showFormForScreenshots = true + config.useShakeGesture = true + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource(), + notificationCenter: notificationCenter) + XCTAssertEqual(notificationCenter.observerCount, 2) + + sut.setShakeGestureEnabled(false) + + // Only the shake observer is removed; the screenshot observer survives. + let removals = notificationCenter.removeObserverWithNameAndObjectInvocations.invocations + XCTAssertEqual(removals.count, 1) + XCTAssertEqual(removals.first?.name, .SentryShakeDetected) + XCTAssertEqual(notificationCenter.observerCount, 1) + + withExtendedLifetime(sut) { } + } + + func testSetShakeGestureEnabled_whenDisabledWhileNotObserving_shouldBeNoOp() { + let notificationCenter = TestNSNotificationCenterWrapper() + let config = SentryUserFeedbackConfiguration() + config.useShakeGesture = false + let sut = SentryUserFeedbackIntegrationDriver( + configuration: config, + screenshotSource: makeScreenshotSource(), + notificationCenter: notificationCenter) + + sut.setShakeGestureEnabled(false) + + XCTAssertTrue(notificationCenter.removeObserverWithNameAndObjectInvocations.invocations.isEmpty) + XCTAssertFalse(config.useShakeGesture) + + withExtendedLifetime(sut) { } + } + + func testFeedbackAPI_setShakeGestureEnabled_whenConfigured_shouldPresentFormOnShake() throws { + let window = makeWindow() + let viewController = TestPresentingViewController() + let integration = try installFeedbackIntegration { $0.animations = false } + useFallbackPresenter(viewController, in: window) + + // Not observing yet (useShakeGesture defaults to false) — a shake is ignored. + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + XCTAssertFalse(integration.driver.displayingForm) + + SentrySDK.feedback.setShakeGestureEnabled(true) + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + + _ = try XCTUnwrap(viewController.lastPresentedViewController as? SentryUserFeedbackFormController) + XCTAssertTrue(integration.driver.displayingForm) + + withExtendedLifetime(window) { } + } + + func testFeedbackAPI_setShakeGestureEnabled_whenFeedbackNotConfigured_shouldNotCrash() { + clearTestState() + + SentrySDK.feedback.setShakeGestureEnabled(true) + SentrySDK.feedback.setShakeGestureEnabled(false) + } + @available(*, deprecated, message: "Testing deprecated widget configuration") func testScreenshotTrigger_whenWidgetAutoInjectionDisabled_shouldUseFallbackPresenter() throws { #if SDK_V10 diff --git a/sdk_api.json b/sdk_api.json index df153a8791c..d2e911b4b41 100644 --- a/sdk_api.json +++ b/sdk_api.json @@ -39799,6 +39799,34 @@ "printedName": "hideWidget()", "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)hideWidget" }, + { + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + }, + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ], + "declAttributes": [ + "Available", + "Final", + "ObjC" + ], + "declKind": "Func", + "funcSelfKind": "NonMutating", + "kind": "Function", + "mangledName": "$s6Sentry0A11FeedbackAPIC22setShakeGestureEnabledyySbF", + "moduleName": "Sentry", + "name": "setShakeGestureEnabled", + "printedName": "setShakeGestureEnabled(_:)", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)setShakeGestureEnabled:" + }, { "children": [ { diff --git a/sdk_api_objc.json b/sdk_api_objc.json index 98e3b6fab4c..b556620c1da 100644 --- a/sdk_api_objc.json +++ b/sdk_api_objc.json @@ -6898,6 +6898,13 @@ "returnType": "void", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "setShakeGestureEnabled:", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "setShowBranding:", diff --git a/sdk_api_objc_v10.json b/sdk_api_objc_v10.json index b3de0644f0a..4f57625bd1c 100644 --- a/sdk_api_objc_v10.json +++ b/sdk_api_objc_v10.json @@ -7172,6 +7172,13 @@ "returnType": "void", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "setShakeGestureEnabled:", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "setShowBranding:", diff --git a/sdk_api_v10.json b/sdk_api_v10.json index c26078fdb6e..7b02e2a5a07 100644 --- a/sdk_api_v10.json +++ b/sdk_api_v10.json @@ -41861,6 +41861,34 @@ "printedName": "init()", "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)init" }, + { + "children": [ + { + "kind": "TypeNominal", + "name": "Bool", + "printedName": "Swift.Bool", + "usr": "s:Sb" + }, + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ], + "declAttributes": [ + "Available", + "Final", + "ObjC" + ], + "declKind": "Func", + "funcSelfKind": "NonMutating", + "kind": "Function", + "mangledName": "$s6Sentry0A11FeedbackAPIC22setShakeGestureEnabledyySbF", + "moduleName": "Sentry", + "name": "setShakeGestureEnabled", + "printedName": "setShakeGestureEnabled(_:)", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)setShakeGestureEnabled:" + }, { "children": [ { From 95d26bd343abea4ffc5ffb5e5a78766d38734b23 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 29 Jul 2026 15:28:21 +0200 Subject: [PATCH 2/6] ref: Update changelog ref to PR number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 933a264c8b4..71c30238646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ ### Features - Add `Breadcrumb.setData(value:key:)` to set a single breadcrumb data entry and deprecate the `Breadcrumb.data` setter in its favor. (#8572) -- Add `SentrySDK.feedback.setShakeGestureEnabled(_:)` to toggle the shake-to-report gesture at runtime (#7970) +- Add `SentrySDK.feedback.setShakeGestureEnabled(_:)` to toggle the shake-to-report gesture at runtime (#8591) ### Fixes From 85b1d3dc6189ec6695f150d8110bb0696edbd71d Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 29 Jul 2026 16:08:41 +0200 Subject: [PATCH 3/6] ref: Rename shake-to-report runtime API methods Replace the single setShakeGestureEnabled(_:) toggle with enableFeedbackOnShake() and disableFeedbackOnShake(), aligning the naming with the Android and React Native SDKs. --- CHANGELOG.md | 2 +- .../SentryObjC/Public/SentryObjCFeedbackApi.h | 16 ++++--- .../SentryObjCFeedbackApi.swift | 9 +++- .../UserFeedback/SentryFeedbackAPI.swift | 23 ++++++++-- .../SentryObjCFeedbackApiTests.m | 6 +-- .../UserFeedbackIntegrationTests.swift | 28 +++++++++--- sdk_api.json | 44 +++++++++++++------ sdk_api_objc.json | 21 ++++++--- sdk_api_objc_v10.json | 21 ++++++--- sdk_api_v10.json | 32 ++++++++++---- 10 files changed, 146 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71c30238646..9b4188c6e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ ### Features - Add `Breadcrumb.setData(value:key:)` to set a single breadcrumb data entry and deprecate the `Breadcrumb.data` setter in its favor. (#8572) -- Add `SentrySDK.feedback.setShakeGestureEnabled(_:)` to toggle the shake-to-report gesture at runtime (#8591) +- Add `SentrySDK.feedback.enableFeedbackOnShake()` and `disableFeedbackOnShake()` to toggle the shake-to-report gesture at runtime (#8591) ### Fixes diff --git a/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h b/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h index 9d531f9f907..4766da86950 100644 --- a/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h +++ b/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h @@ -62,16 +62,22 @@ SENTRY_NO_INIT NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); /** - * Enables or disables the shake-gesture trigger for the feedback form at runtime. - * @discussion Use this to toggle shake-to-report after @c SentrySDK.start, e.g. once an + * Enables the shake-gesture trigger for the feedback form at runtime. + * @discussion Use this to enable shake-to-report after @c SentrySDK.start, e.g. once an * asynchronously fetched feature flag resolves. Requires the User Feedback integration to be * configured; otherwise this is a no-op. - * @param enabled @c YES to start presenting the feedback form on shake; @c NO to stop. * @note This method must be called from the main thread. * @warning This is an experimental feature and may still have bugs. */ -- (void)setShakeGestureEnabled:(BOOL)enabled - NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); +- (void)enableFeedbackOnShake NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); + +/** + * Disables the shake-gesture trigger for the feedback form at runtime. + * @discussion Requires the User Feedback integration to be configured; otherwise this is a no-op. + * @note This method must be called from the main thread. + * @warning This is an experimental feature and may still have bugs. + */ +- (void)disableFeedbackOnShake NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); # if !SDK_V10 /** diff --git a/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift b/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift index 83ef0afa8a6..8693d4d6f2b 100644 --- a/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift +++ b/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift @@ -40,8 +40,13 @@ import UIKit } @available(iOSApplicationExtension, unavailable) - @objc public func setShakeGestureEnabled(_ enabled: Bool) { - wrapped.setShakeGestureEnabled(enabled) + @objc public func enableFeedbackOnShake() { + wrapped.enableFeedbackOnShake() + } + + @available(iOSApplicationExtension, unavailable) + @objc public func disableFeedbackOnShake() { + wrapped.disableFeedbackOnShake() } #if !SDK_V10 diff --git a/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift b/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift index 69573bc9912..8243d3693bf 100644 --- a/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift +++ b/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift @@ -61,20 +61,35 @@ import UIKit driver.showForm(from: presenter, screenshot: screenshot, configure: configure) } - /// Enables or disables the shake-gesture trigger for the feedback form at runtime. + /// Enables the shake-gesture trigger for the feedback form at runtime. /// /// Sentry's options are applied synchronously during `SentrySDK.start`, so consumers that /// decide whether to offer feedback based on an asynchronous signal (e.g. a feature flag or a /// user role fetched at launch) cannot express that choice through `useShakeGesture` alone. - /// Use this method to toggle shake-to-report after initialization. + /// Use this to enable shake-to-report after initialization. /// /// Requires the User Feedback integration to be configured (`SentryOptions.configureUserFeedback`); /// otherwise this is a no-op. Only affects iOS/iPadOS; a no-op on other platforms. - /// - Parameter enabled: `true` to start presenting the feedback form on shake; `false` to stop. /// - Important: Call this method from the main thread. /// - warning: This is an experimental feature and may still have bugs. @available(iOSApplicationExtension, unavailable) - @objc public func setShakeGestureEnabled(_ enabled: Bool) { + @objc public func enableFeedbackOnShake() { + setShakeGestureEnabled(true) + } + + /// Disables the shake-gesture trigger for the feedback form at runtime. + /// + /// Requires the User Feedback integration to be configured (`SentryOptions.configureUserFeedback`); + /// otherwise this is a no-op. Only affects iOS/iPadOS; a no-op on other platforms. + /// - Important: Call this method from the main thread. + /// - warning: This is an experimental feature and may still have bugs. + @available(iOSApplicationExtension, unavailable) + @objc public func disableFeedbackOnShake() { + setShakeGestureEnabled(false) + } + + @available(iOSApplicationExtension, unavailable) + private func setShakeGestureEnabled(_ enabled: Bool) { guard let driver = getIntegration()?.driver else { SentrySDKLog.debug("Cannot toggle shake gesture — user feedback is not configured") return diff --git a/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m b/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m index f7b6c76c4f1..62cdd61871d 100644 --- a/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m +++ b/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m @@ -40,11 +40,11 @@ - (void)testShowWithScreenshotAndConfigure_whenNoPresenter_shouldNotCrash }]; } -- (void)testSetShakeGestureEnabled_whenFeedbackNotConfigured_shouldNotCrash +- (void)testFeedbackOnShake_whenFeedbackNotConfigured_shouldNotCrash { // -- Act & Assert (no crash) -- - [SentryObjCSDK.feedback setShakeGestureEnabled:YES]; - [SentryObjCSDK.feedback setShakeGestureEnabled:NO]; + [SentryObjCSDK.feedback enableFeedbackOnShake]; + [SentryObjCSDK.feedback disableFeedbackOnShake]; } @end diff --git a/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift b/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift index cc48cdb61de..61bd252acd7 100644 --- a/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift @@ -495,7 +495,7 @@ final class UserFeedbackIntegrationTests: XCTestCase { withExtendedLifetime(sut) { } } - func testFeedbackAPI_setShakeGestureEnabled_whenConfigured_shouldPresentFormOnShake() throws { + func testFeedbackAPI_enableFeedbackOnShake_whenConfigured_shouldPresentFormOnShake() throws { let window = makeWindow() let viewController = TestPresentingViewController() let integration = try installFeedbackIntegration { $0.animations = false } @@ -505,7 +505,7 @@ final class UserFeedbackIntegrationTests: XCTestCase { NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) XCTAssertFalse(integration.driver.displayingForm) - SentrySDK.feedback.setShakeGestureEnabled(true) + SentrySDK.feedback.enableFeedbackOnShake() NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) _ = try XCTUnwrap(viewController.lastPresentedViewController as? SentryUserFeedbackFormController) @@ -514,11 +514,29 @@ final class UserFeedbackIntegrationTests: XCTestCase { withExtendedLifetime(window) { } } - func testFeedbackAPI_setShakeGestureEnabled_whenFeedbackNotConfigured_shouldNotCrash() { + func testFeedbackAPI_disableFeedbackOnShake_whenConfigured_shouldSuppressFormOnShake() throws { + let window = makeWindow() + let viewController = TestPresentingViewController() + let integration = try installFeedbackIntegration { + $0.animations = false + $0.useShakeGesture = true + } + useFallbackPresenter(viewController, in: window) + + SentrySDK.feedback.disableFeedbackOnShake() + NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) + + XCTAssertFalse(integration.driver.displayingForm) + XCTAssertEqual(viewController.presentCallCount, 0) + + withExtendedLifetime(window) { } + } + + func testFeedbackAPI_feedbackOnShake_whenFeedbackNotConfigured_shouldNotCrash() { clearTestState() - SentrySDK.feedback.setShakeGestureEnabled(true) - SentrySDK.feedback.setShakeGestureEnabled(false) + SentrySDK.feedback.enableFeedbackOnShake() + SentrySDK.feedback.disableFeedbackOnShake() } @available(*, deprecated, message: "Testing deprecated widget configuration") diff --git a/sdk_api.json b/sdk_api.json index d2e911b4b41..794c7ae82ca 100644 --- a/sdk_api.json +++ b/sdk_api.json @@ -39784,29 +39784,43 @@ } ], "declAttributes": [ - "Available", "Available", "Final", "ObjC" ], "declKind": "Func", - "deprecated": true, "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC10hideWidgetyyF", + "mangledName": "$s6Sentry0A11FeedbackAPIC07disableB7OnShakeyyF", "moduleName": "Sentry", - "name": "hideWidget", - "printedName": "hideWidget()", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)hideWidget" + "name": "disableFeedbackOnShake", + "printedName": "disableFeedbackOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)disableFeedbackOnShake" }, { "children": [ { "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - }, + "name": "Void", + "printedName": "()" + } + ], + "declAttributes": [ + "Available", + "Final", + "ObjC" + ], + "declKind": "Func", + "funcSelfKind": "NonMutating", + "kind": "Function", + "mangledName": "$s6Sentry0A11FeedbackAPIC06enableB7OnShakeyyF", + "moduleName": "Sentry", + "name": "enableFeedbackOnShake", + "printedName": "enableFeedbackOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)enableFeedbackOnShake" + }, + { + "children": [ { "kind": "TypeNominal", "name": "Void", @@ -39814,18 +39828,20 @@ } ], "declAttributes": [ + "Available", "Available", "Final", "ObjC" ], "declKind": "Func", + "deprecated": true, "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC22setShakeGestureEnabledyySbF", + "mangledName": "$s6Sentry0A11FeedbackAPIC10hideWidgetyyF", "moduleName": "Sentry", - "name": "setShakeGestureEnabled", - "printedName": "setShakeGestureEnabled(_:)", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)setShakeGestureEnabled:" + "name": "hideWidget", + "printedName": "hideWidget()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)hideWidget" }, { "children": [ diff --git a/sdk_api_objc.json b/sdk_api_objc.json index b556620c1da..2ec307c5693 100644 --- a/sdk_api_objc.json +++ b/sdk_api_objc.json @@ -1746,6 +1746,13 @@ "returnType": "SentryObjCLevel", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "disableFeedbackOnShake", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "discardFor:", @@ -1949,6 +1956,13 @@ "returnType": "BOOL", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "enableFeedbackOnShake", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "enableFileIOTracing", @@ -6898,13 +6912,6 @@ "returnType": "void", "instance": true }, - { - "kind": "ObjCMethodDecl", - "name": "setShakeGestureEnabled:", - "parent": "SentryObjCFeedbackApi", - "returnType": "void", - "instance": true - }, { "kind": "ObjCMethodDecl", "name": "setShowBranding:", diff --git a/sdk_api_objc_v10.json b/sdk_api_objc_v10.json index 4f57625bd1c..ff81d739fb4 100644 --- a/sdk_api_objc_v10.json +++ b/sdk_api_objc_v10.json @@ -1852,6 +1852,13 @@ "returnType": "SentryObjCLevel", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "disableFeedbackOnShake", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "discardFor:", @@ -2062,6 +2069,13 @@ "returnType": "BOOL", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "enableFeedbackOnShake", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "enableFileIOTracing", @@ -7172,13 +7186,6 @@ "returnType": "void", "instance": true }, - { - "kind": "ObjCMethodDecl", - "name": "setShakeGestureEnabled:", - "parent": "SentryObjCFeedbackApi", - "returnType": "void", - "instance": true - }, { "kind": "ObjCMethodDecl", "name": "setShowBranding:", diff --git a/sdk_api_v10.json b/sdk_api_v10.json index 7b02e2a5a07..8fb09f7ac2e 100644 --- a/sdk_api_v10.json +++ b/sdk_api_v10.json @@ -41865,10 +41865,26 @@ "children": [ { "kind": "TypeNominal", - "name": "Bool", - "printedName": "Swift.Bool", - "usr": "s:Sb" - }, + "name": "Void", + "printedName": "()" + } + ], + "declAttributes": [ + "Available", + "Final", + "ObjC" + ], + "declKind": "Func", + "funcSelfKind": "NonMutating", + "kind": "Function", + "mangledName": "$s6Sentry0A11FeedbackAPIC07disableB7OnShakeyyF", + "moduleName": "Sentry", + "name": "disableFeedbackOnShake", + "printedName": "disableFeedbackOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)disableFeedbackOnShake" + }, + { + "children": [ { "kind": "TypeNominal", "name": "Void", @@ -41883,11 +41899,11 @@ "declKind": "Func", "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC22setShakeGestureEnabledyySbF", + "mangledName": "$s6Sentry0A11FeedbackAPIC06enableB7OnShakeyyF", "moduleName": "Sentry", - "name": "setShakeGestureEnabled", - "printedName": "setShakeGestureEnabled(_:)", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)setShakeGestureEnabled:" + "name": "enableFeedbackOnShake", + "printedName": "enableFeedbackOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)enableFeedbackOnShake" }, { "children": [ From f8b34f711d201fad24e32f334037982e7fbb2bba Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Thu, 30 Jul 2026 09:20:38 +0200 Subject: [PATCH 4/6] chore: Move shake feedback changelog to Unreleased --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb146f49fa6..f0952632ee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- Add `SentrySDK.feedback.enableFeedbackOnShake()` and `disableFeedbackOnShake()` to toggle the shake-to-report gesture at runtime (#8591) + ## 9.24.0 ### Breaking Changes @@ -14,7 +20,6 @@ ### Features - Add `Breadcrumb.setData(value:key:)` to set a single breadcrumb data entry and deprecate the `Breadcrumb.data` setter in its favor. (#8572) -- Add `SentrySDK.feedback.enableFeedbackOnShake()` and `disableFeedbackOnShake()` to toggle the shake-to-report gesture at runtime (#8591) ### Fixes From 04e07e098c248427e8935d1e1a8524e817a30911 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Thu, 30 Jul 2026 10:25:39 +0200 Subject: [PATCH 5/6] Enhance the sample app for testing --- .../App/Resources/Base.lproj/Main.storyboard | 16 ++++++++++++++++ .../App/Sources/FeedbackViewController.swift | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/Samples/iOS-Swift/App/Resources/Base.lproj/Main.storyboard b/Samples/iOS-Swift/App/Resources/Base.lproj/Main.storyboard index 9ab3d4cad9a..88a658745ec 100644 --- a/Samples/iOS-Swift/App/Resources/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/App/Resources/Base.lproj/Main.storyboard @@ -1998,6 +1998,22 @@ + + diff --git a/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift b/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift index afc42b1f91d..7800dc062d8 100644 --- a/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift +++ b/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift @@ -30,6 +30,14 @@ final class FeedbackViewController: UIViewController { } } + @IBAction private func enableFeedbackOnShake(_: UIButton) { + SentrySDK.feedback.enableFeedbackOnShake() + } + + @IBAction private func disableFeedbackOnShake(_: UIButton) { + SentrySDK.feedback.disableFeedbackOnShake() + } + @IBAction private func toggleWidget(_: UIButton) { if isFeedbackWidgetVisible { SentrySDK.feedback.hideWidget() From 790713a1f47dd667b1a69562798b7c9d3634a37a Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Fri, 31 Jul 2026 15:24:51 +0200 Subject: [PATCH 6/6] Rename to methods to enableOnShake() and disableOnShake() --- CHANGELOG.md | 7 ++++--- .../App/Sources/FeedbackViewController.swift | 4 ++-- .../SentryObjC/Public/SentryObjCFeedbackApi.h | 4 ++-- .../SentryObjCCompat/SentryObjCFeedbackApi.swift | 8 ++++---- .../UserFeedback/SentryFeedbackAPI.swift | 4 ++-- .../SentryObjCTests/SentryObjCFeedbackApiTests.m | 6 +++--- .../Feedback/UserFeedbackIntegrationTests.swift | 14 +++++++------- sdk_api.json | 16 ++++++++-------- sdk_api_objc.json | 16 ++++++++-------- sdk_api_objc_v10.json | 16 ++++++++-------- sdk_api_v10.json | 16 ++++++++-------- 11 files changed, 56 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55ffb8bda88..341285ba9b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,6 @@ ## Unreleased -### Features - -- Add `SentrySDK.feedback.enableFeedbackOnShake()` and `disableFeedbackOnShake()` to toggle the shake-to-report gesture at runtime (#8591) > [!WARNING] > This release raises the minimum deployment targets to macOS 12 and watchOS 9. Apps that support older OS versions must use an earlier Sentry Cocoa release. @@ -12,6 +9,10 @@ - Bump the minimum deployment targets to macOS 12 and watchOS 9 because Xcode 27 no longer supports earlier versions. This lets the SDK adopt Xcode 27 without blocking users from building and submitting their apps with the latest Xcode. (#8595, #8113, #8189) +### Features + +- Add `SentrySDK.feedback.enableOnShake()` and `disableOnShake()` to toggle the shake-to-report gesture at runtime (#8591) + ### Fixes - Fix incorrect `duration` sent for active sessions (#8612) diff --git a/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift b/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift index 7800dc062d8..ec747a9741c 100644 --- a/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift +++ b/Samples/iOS-Swift/App/Sources/FeedbackViewController.swift @@ -31,11 +31,11 @@ final class FeedbackViewController: UIViewController { } @IBAction private func enableFeedbackOnShake(_: UIButton) { - SentrySDK.feedback.enableFeedbackOnShake() + SentrySDK.feedback.enableOnShake() } @IBAction private func disableFeedbackOnShake(_: UIButton) { - SentrySDK.feedback.disableFeedbackOnShake() + SentrySDK.feedback.disableOnShake() } @IBAction private func toggleWidget(_: UIButton) { diff --git a/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h b/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h index 4766da86950..aa660408d45 100644 --- a/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h +++ b/Sources/SentryObjC/Public/SentryObjCFeedbackApi.h @@ -69,7 +69,7 @@ SENTRY_NO_INIT * @note This method must be called from the main thread. * @warning This is an experimental feature and may still have bugs. */ -- (void)enableFeedbackOnShake NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); +- (void)enableOnShake NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); /** * Disables the shake-gesture trigger for the feedback form at runtime. @@ -77,7 +77,7 @@ SENTRY_NO_INIT * @note This method must be called from the main thread. * @warning This is an experimental feature and may still have bugs. */ -- (void)disableFeedbackOnShake NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); +- (void)disableOnShake NS_EXTENSION_UNAVAILABLE("Not available in app extensions."); # if !SDK_V10 /** diff --git a/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift b/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift index 8693d4d6f2b..0af0ebeccb1 100644 --- a/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift +++ b/Sources/SentryObjCCompat/SentryObjCFeedbackApi.swift @@ -40,13 +40,13 @@ import UIKit } @available(iOSApplicationExtension, unavailable) - @objc public func enableFeedbackOnShake() { - wrapped.enableFeedbackOnShake() + @objc public func enableOnShake() { + wrapped.enableOnShake() } @available(iOSApplicationExtension, unavailable) - @objc public func disableFeedbackOnShake() { - wrapped.disableFeedbackOnShake() + @objc public func disableOnShake() { + wrapped.disableOnShake() } #if !SDK_V10 diff --git a/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift b/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift index 8243d3693bf..48c5c1f0097 100644 --- a/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift +++ b/Sources/Swift/Integrations/UserFeedback/SentryFeedbackAPI.swift @@ -73,7 +73,7 @@ import UIKit /// - Important: Call this method from the main thread. /// - warning: This is an experimental feature and may still have bugs. @available(iOSApplicationExtension, unavailable) - @objc public func enableFeedbackOnShake() { + @objc public func enableOnShake() { setShakeGestureEnabled(true) } @@ -84,7 +84,7 @@ import UIKit /// - Important: Call this method from the main thread. /// - warning: This is an experimental feature and may still have bugs. @available(iOSApplicationExtension, unavailable) - @objc public func disableFeedbackOnShake() { + @objc public func disableOnShake() { setShakeGestureEnabled(false) } diff --git a/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m b/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m index 62cdd61871d..6bac300cb81 100644 --- a/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m +++ b/Tests/SentryObjCTests/SentryObjCFeedbackApiTests.m @@ -40,11 +40,11 @@ - (void)testShowWithScreenshotAndConfigure_whenNoPresenter_shouldNotCrash }]; } -- (void)testFeedbackOnShake_whenFeedbackNotConfigured_shouldNotCrash +- (void)testOnShake_whenFeedbackNotConfigured_shouldNotCrash { // -- Act & Assert (no crash) -- - [SentryObjCSDK.feedback enableFeedbackOnShake]; - [SentryObjCSDK.feedback disableFeedbackOnShake]; + [SentryObjCSDK.feedback enableOnShake]; + [SentryObjCSDK.feedback disableOnShake]; } @end diff --git a/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift b/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift index 61bd252acd7..8fab16d2a0b 100644 --- a/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift @@ -495,7 +495,7 @@ final class UserFeedbackIntegrationTests: XCTestCase { withExtendedLifetime(sut) { } } - func testFeedbackAPI_enableFeedbackOnShake_whenConfigured_shouldPresentFormOnShake() throws { + func testFeedbackAPI_enableOnShake_whenConfigured_shouldPresentFormOnShake() throws { let window = makeWindow() let viewController = TestPresentingViewController() let integration = try installFeedbackIntegration { $0.animations = false } @@ -505,7 +505,7 @@ final class UserFeedbackIntegrationTests: XCTestCase { NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) XCTAssertFalse(integration.driver.displayingForm) - SentrySDK.feedback.enableFeedbackOnShake() + SentrySDK.feedback.enableOnShake() NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) _ = try XCTUnwrap(viewController.lastPresentedViewController as? SentryUserFeedbackFormController) @@ -514,7 +514,7 @@ final class UserFeedbackIntegrationTests: XCTestCase { withExtendedLifetime(window) { } } - func testFeedbackAPI_disableFeedbackOnShake_whenConfigured_shouldSuppressFormOnShake() throws { + func testFeedbackAPI_disableOnShake_whenConfigured_shouldSuppressFormOnShake() throws { let window = makeWindow() let viewController = TestPresentingViewController() let integration = try installFeedbackIntegration { @@ -523,7 +523,7 @@ final class UserFeedbackIntegrationTests: XCTestCase { } useFallbackPresenter(viewController, in: window) - SentrySDK.feedback.disableFeedbackOnShake() + SentrySDK.feedback.disableOnShake() NotificationCenter.default.post(name: .SentryShakeDetected, object: nil) XCTAssertFalse(integration.driver.displayingForm) @@ -532,11 +532,11 @@ final class UserFeedbackIntegrationTests: XCTestCase { withExtendedLifetime(window) { } } - func testFeedbackAPI_feedbackOnShake_whenFeedbackNotConfigured_shouldNotCrash() { + func testFeedbackAPI_onShake_whenFeedbackNotConfigured_shouldNotCrash() { clearTestState() - SentrySDK.feedback.enableFeedbackOnShake() - SentrySDK.feedback.disableFeedbackOnShake() + SentrySDK.feedback.enableOnShake() + SentrySDK.feedback.disableOnShake() } @available(*, deprecated, message: "Testing deprecated widget configuration") diff --git a/sdk_api.json b/sdk_api.json index 0170bf4355e..27ff05051a8 100644 --- a/sdk_api.json +++ b/sdk_api.json @@ -39867,11 +39867,11 @@ "declKind": "Func", "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC07disableB7OnShakeyyF", + "mangledName": "$s6Sentry0A11FeedbackAPIC14disableOnShakeyyF", "moduleName": "Sentry", - "name": "disableFeedbackOnShake", - "printedName": "disableFeedbackOnShake()", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)disableFeedbackOnShake" + "name": "disableOnShake", + "printedName": "disableOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)disableOnShake" }, { "children": [ @@ -39889,11 +39889,11 @@ "declKind": "Func", "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC06enableB7OnShakeyyF", + "mangledName": "$s6Sentry0A11FeedbackAPIC13enableOnShakeyyF", "moduleName": "Sentry", - "name": "enableFeedbackOnShake", - "printedName": "enableFeedbackOnShake()", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)enableFeedbackOnShake" + "name": "enableOnShake", + "printedName": "enableOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)enableOnShake" }, { "children": [ diff --git a/sdk_api_objc.json b/sdk_api_objc.json index 5ac65cc9c2d..72823bf2964 100644 --- a/sdk_api_objc.json +++ b/sdk_api_objc.json @@ -1748,7 +1748,7 @@ }, { "kind": "ObjCMethodDecl", - "name": "disableFeedbackOnShake", + "name": "disableOnShake", "parent": "SentryObjCFeedbackApi", "returnType": "void", "instance": true @@ -1956,13 +1956,6 @@ "returnType": "BOOL", "instance": true }, - { - "kind": "ObjCMethodDecl", - "name": "enableFeedbackOnShake", - "parent": "SentryObjCFeedbackApi", - "returnType": "void", - "instance": true - }, { "kind": "ObjCMethodDecl", "name": "enableFileIOTracing", @@ -2033,6 +2026,13 @@ "returnType": "BOOL", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "enableOnShake", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "enablePersistingTracesWhenCrashing", diff --git a/sdk_api_objc_v10.json b/sdk_api_objc_v10.json index 3ebe425f3a1..fbf8d0c06a0 100644 --- a/sdk_api_objc_v10.json +++ b/sdk_api_objc_v10.json @@ -1854,7 +1854,7 @@ }, { "kind": "ObjCMethodDecl", - "name": "disableFeedbackOnShake", + "name": "disableOnShake", "parent": "SentryObjCFeedbackApi", "returnType": "void", "instance": true @@ -2069,13 +2069,6 @@ "returnType": "BOOL", "instance": true }, - { - "kind": "ObjCMethodDecl", - "name": "enableFeedbackOnShake", - "parent": "SentryObjCFeedbackApi", - "returnType": "void", - "instance": true - }, { "kind": "ObjCMethodDecl", "name": "enableFileIOTracing", @@ -2146,6 +2139,13 @@ "returnType": "BOOL", "instance": true }, + { + "kind": "ObjCMethodDecl", + "name": "enableOnShake", + "parent": "SentryObjCFeedbackApi", + "returnType": "void", + "instance": true + }, { "kind": "ObjCMethodDecl", "name": "enablePersistingTracesWhenCrashing", diff --git a/sdk_api_v10.json b/sdk_api_v10.json index 516fd95032b..2e2af506f46 100644 --- a/sdk_api_v10.json +++ b/sdk_api_v10.json @@ -41953,11 +41953,11 @@ "declKind": "Func", "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC07disableB7OnShakeyyF", + "mangledName": "$s6Sentry0A11FeedbackAPIC14disableOnShakeyyF", "moduleName": "Sentry", - "name": "disableFeedbackOnShake", - "printedName": "disableFeedbackOnShake()", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)disableFeedbackOnShake" + "name": "disableOnShake", + "printedName": "disableOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)disableOnShake" }, { "children": [ @@ -41975,11 +41975,11 @@ "declKind": "Func", "funcSelfKind": "NonMutating", "kind": "Function", - "mangledName": "$s6Sentry0A11FeedbackAPIC06enableB7OnShakeyyF", + "mangledName": "$s6Sentry0A11FeedbackAPIC13enableOnShakeyyF", "moduleName": "Sentry", - "name": "enableFeedbackOnShake", - "printedName": "enableFeedbackOnShake()", - "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)enableFeedbackOnShake" + "name": "enableOnShake", + "printedName": "enableOnShake()", + "usr": "c:@M@Sentry@objc(cs)SentryFeedbackAPI(im)enableOnShake" }, { "children": [