-
-
Notifications
You must be signed in to change notification settings - Fork 226
Session Replay for iOS #4664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: version6
Are you sure you want to change the base?
Session Replay for iOS #4664
Changes from all commits
5044bb2
faa8955
2b38e74
34308e1
fd44770
24a1894
d932572
7e1ef56
241d0d8
6696c12
28efafc
9a504f3
d4be03c
f8cf3a8
21a86be
15a8b02
830be9a
f69b682
3cb7ff6
1afac38
f8eef20
e34869e
74610f8
79a385b
6cc4c84
8a4057e
bb48bea
0bdee43
f6d9119
db67798
e366852
eda4876
85f6fa5
49c1000
5339c6b
a46c385
b6db1e3
d38c428
59f6d78
63316c8
18aabbf
b595c57
e02c641
d168d49
0efe682
bd44d54
ee4a34b
6fc1c5e
f93b903
7e962ef
c426d61
a1d4b66
857f793
32714c0
947d6e9
25007aa
10a178c
f79fc89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -267,6 +267,104 @@ public void AddInAppInclude(string prefix) | |
| InAppIncludes ??= new List<string>(); | ||
| InAppIncludes.Add(prefix); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Options for experimental features in the native Sentry Cocoa SDK. | ||
| /// </summary> | ||
| public class NativeExperimentalOptions | ||
| { | ||
| /// <summary> | ||
| /// Session Replay options. | ||
| /// </summary> | ||
| public NativeSentryReplayOptions SessionReplay { get; set; } = new(); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Session Replay options for the native Sentry Cocoa SDK. | ||
| /// </summary> | ||
| public class NativeSentryReplayOptions | ||
| { | ||
| /// <summary> | ||
| /// <para> | ||
| /// Forces enabling of session replay in unreliable environments. | ||
| /// </para> | ||
| /// <para> | ||
| /// Due to internal changes with the release of Liquid Glass on iOS 26.0, the masking of text and images can | ||
| /// not be reliably guaranteed. Therefore the SDK uses a defensive programming approach to disable the | ||
| /// session replay integration by default, unless the environment is detected as reliable. | ||
| /// </para> | ||
| /// <para> | ||
| /// Indicators for reliable environments include: | ||
| /// <list type="bullet"> | ||
| /// <item> | ||
| /// <description>Running on an older version of iOS that doesn't have Liquid Glass (iOS 18 or earlier)</description> | ||
| /// </item> | ||
| /// <item> | ||
| /// <description><c>UIDesignRequiresCompatibility</c> is explicitly set to <c>YES</c> in <c>Info.plist</c></description> | ||
| /// </item> | ||
| /// <item> | ||
| /// <description>The app was built with Xcode < 26.0 (DTXcode < 2600)</description> | ||
| /// </item> | ||
| /// </list> | ||
| /// </para> | ||
| /// <para> | ||
| /// Important: This flag allows to re-enable the session replay integration on iOS 26.0 and later, but please be aware that text and images may not be masked as expected. | ||
| /// </para> | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// See https://github.com/getsentry/sentry-cocoa/issues/6389 | ||
| /// </remarks> | ||
| public bool EnableSessionReplayInUnreliableEnvironment { get; set; } = false; | ||
|
|
||
| /// <summary> | ||
| /// The sample rate for sessions that had an error or crash. | ||
| /// Value must be between 0.0 and 1.0. | ||
| /// A value of 0.0 disables session replay for errored sessions. | ||
| /// A value of 1.0 captures session replay for all errored sessions. | ||
| /// </summary> | ||
| public double? OnErrorSampleRate { get; set; } | ||
| /// <summary> | ||
| /// The sample rate for all sessions. | ||
| /// Value must be between 0.0 and 1.0. | ||
| /// A value of 0.0 disables session replay for all sessions. | ||
| /// A value of 1.0 captures session replay for all sessions. | ||
| /// </summary> | ||
| public double? SessionSampleRate { get; set; } | ||
| /// <summary> | ||
| /// Whether to mask all images in the session replay by default. | ||
| /// </summary> | ||
| public bool MaskAllImages { get; set; } = true; | ||
| /// <summary> | ||
| /// Whether to mask all text in the session replay by default. | ||
| /// </summary> | ||
| public bool MaskAllText { get; set; } = true; | ||
|
|
||
| /// <summary> | ||
| /// When enabled, reduces the impact of Session Replay on the main thread and potential frame drops. This is | ||
| /// the default and recommended setting, but if you are experiencing issues then you can opt out by setting | ||
| /// to <c>false</c>. | ||
| /// </summary> | ||
| /// <remarks>Defaults to <c>true</c></remarks> | ||
| public bool EnableViewRendererV2 { get; set; } = true; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: are
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They're separate flags in the underlying Cocoa SDK... we don't actually need to surface these in .NET though. I could just remove them unless/until we have some need to expose them. |
||
|
|
||
| /// <summary> | ||
| /// <para> | ||
| /// Enables faster rendering of views at the cost of some visual fidelity. | ||
| /// </para> | ||
| /// <para> | ||
| /// See: https://blog.sentry.io/boosting-session-replay-performance-on-ios-with-view-renderer-v2/ | ||
| /// </para> | ||
| /// </summary> | ||
| /// <remarks>Defaults to <c>false</c></remarks> | ||
| public bool EnableFastViewRendering { get; set; } = false; | ||
|
|
||
| internal bool IsSessionReplayEnabled => OnErrorSampleRate > 0.0 || SessionSampleRate > 0.0; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// ExperimentalOptions | ||
| /// </summary> | ||
| public NativeExperimentalOptions ExperimentalOptions { get; set; } = new(); | ||
| } | ||
|
|
||
| // We actually add the profiling integration automatically in InitSentryCocoaSdk(). | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -145,6 +145,29 @@ private static void InitSentryCocoaSdk(SentryOptions options) | |||||||||||||||||||||||||||||||||||||||||||||
| // nativeOptions.DefaultIntegrations | ||||||||||||||||||||||||||||||||||||||||||||||
| // nativeOptions.EnableProfiling (deprecated) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Session Replay options for the Cocoa SDK | ||||||||||||||||||||||||||||||||||||||||||||||
| if (options.Native.ExperimentalOptions.SessionReplay.IsSessionReplayEnabled) | ||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||
| // For replay to work on iOS, session tracking must be enabled in the Cocoa SDK | ||||||||||||||||||||||||||||||||||||||||||||||
| options.AutoSessionTracking = false; | ||||||||||||||||||||||||||||||||||||||||||||||
| nativeOptions.EnableAutoSessionTracking = true; | ||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how we now want to handle situations like this: sentry-dotnet/src/Sentry/SentryClient.cs Lines 350 to 362 in 9d1b4fe
... or this: sentry-dotnet/src/Sentry/Internal/Hub.cs Lines 376 to 384 in 9d1b4fe
If the CocoaSdk owns the session, do we still need to be able to start/stop sessions from the .NET SDK?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these sessions are not the same as session replay. let's not conflate these APIs |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // SDK users must explicitly opt-in to Session Replay in unreliable environments | ||||||||||||||||||||||||||||||||||||||||||||||
| nativeOptions.Experimental.EnableSessionReplayInUnreliableEnvironment = | ||||||||||||||||||||||||||||||||||||||||||||||
| options.Native.ExperimentalOptions.SessionReplay.EnableSessionReplayInUnreliableEnvironment; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| var sessionSampleRate = (float)(options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate ?? 0f); | ||||||||||||||||||||||||||||||||||||||||||||||
| var onErrorSampleRate = (float)(options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate ?? 0f); | ||||||||||||||||||||||||||||||||||||||||||||||
| var cocoaReplayOptions = new Sentry.CocoaSdk.SentryReplayOptions(); | ||||||||||||||||||||||||||||||||||||||||||||||
| cocoaReplayOptions.SessionSampleRate = sessionSampleRate; | ||||||||||||||||||||||||||||||||||||||||||||||
| cocoaReplayOptions.OnErrorSampleRate = onErrorSampleRate; | ||||||||||||||||||||||||||||||||||||||||||||||
| cocoaReplayOptions.MaskAllText = options.Native.ExperimentalOptions.SessionReplay.MaskAllText; | ||||||||||||||||||||||||||||||||||||||||||||||
| cocoaReplayOptions.MaskAllImages = options.Native.ExperimentalOptions.SessionReplay.MaskAllImages; | ||||||||||||||||||||||||||||||||||||||||||||||
| cocoaReplayOptions.EnableViewRendererV2 = options.Native.ExperimentalOptions.SessionReplay.EnableViewRendererV2; | ||||||||||||||||||||||||||||||||||||||||||||||
| cocoaReplayOptions.EnableFastViewRendering = options.Native.ExperimentalOptions.SessionReplay.EnableFastViewRendering; | ||||||||||||||||||||||||||||||||||||||||||||||
| nativeOptions.SessionReplay = cocoaReplayOptions; | ||||||||||||||||||||||||||||||||||||||||||||||
jamescrosswell marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Set hybrid SDK name | ||||||||||||||||||||||||||||||||||||||||||||||
| SentryCocoaHybridSdk.SetSdkName("sentry.cocoa.dotnet"); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.