Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@

See https://develop.sentry.dev/sdk/telemetry/traces/distributed-tracing/#w3c-trace-context-header for more details.

### Features

- Added experimental support for Session Replay on iOS ([#4664](https://github.com/getsentry/sentry-dotnet/pull/4664))

### Fixes

- The SDK avoids redundant scope sync after transaction finish ([#4623](https://github.com/getsentry/sentry-dotnet/pull/4623))
Expand Down
6 changes: 4 additions & 2 deletions samples/Sentry.Samples.Maui/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,22 @@
// Automatically create traces for async relay commands in the MVVM Community Toolkit
options.AddCommunityToolkitIntegration();

#if __ANDROID__
// Currently, experimental support is only available on Android
#if __ANDROID__ || __IOS__ || __MACCATALYST__
// Experimental support for Session Replay is currently available on Android, iOS and Mac Catalyst.
options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate = 1.0;

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 49 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)
options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate = 1.0;

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 50 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)
// Mask all images and text by default. This can be overridden for individual view elements via the
// sentry:SessionReplay.Mask XML attribute (see MainPage.xaml for an example)
options.Native.ExperimentalOptions.SessionReplay.MaskAllImages = true;

Check failure on line 53 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 53 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 53 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 53 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 53 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 53 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)
options.Native.ExperimentalOptions.SessionReplay.MaskAllText = true;

Check failure on line 54 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 54 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / MSBuild

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 54 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 54 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 54 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 54 in samples/Sentry.Samples.Maui/MauiProgram.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

'SentryMauiOptions' does not contain a definition for 'Native' and no accessible extension method 'Native' accepting a first argument of type 'SentryMauiOptions' could be found (are you missing a using directive or an assembly reference?)
#if __ANDROID__
// Alternatively, the masking behaviour for entire classes of VisualElements can be configured here as
// an exception to the default behaviour.
// WARNING: In apps with complex user interfaces, consisting of hundreds of visual controls on a single
// page, this option may cause performance issues. In such cases, consider applying the
// sentry:SessionReplay.Mask="Unmask" attribute to individual controls instead.
options.Native.ExperimentalOptions.SessionReplay.UnmaskControlsOfType<Button>();
#endif
#endif

options.SetBeforeScreenshotCapture((@event, hint) =>
Expand Down
7 changes: 0 additions & 7 deletions src/Sentry.Bindings.Cocoa/SwiftApiDefinitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,6 @@ interface SentryReplayOptions //: ISentryRedactOptions
// @property (readonly, nonatomic) NSTimeInterval maximumDuration;
[Export ("maximumDuration")]
double MaximumDuration { get; }
// -(instancetype _Nonnull)initWithSessionSampleRate:(float)sessionSampleRate onErrorSampleRate:(float)onErrorSampleRate maskAllText:(BOOL)maskAllText maskAllImages:(BOOL)maskAllImages __attribute__((objc_designated_initializer));
[Export ("initWithSessionSampleRate:onErrorSampleRate:maskAllText:maskAllImages:")]
[DesignatedInitializer]
NativeHandle Constructor (float sessionSampleRate, float onErrorSampleRate, bool maskAllText, bool maskAllImages);
// -(instancetype _Nonnull)initWithDictionary:(NSDictionary<NSString *,id> * _Nonnull)dictionary;
[Export ("initWithDictionary:")]
NativeHandle Constructor (NSDictionary<NSString, NSObject> dictionary);
*/
}

Expand Down
4 changes: 4 additions & 0 deletions src/Sentry/Internal/ReplaySession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public SentryId? ActiveReplayId
// Check to see if a Replay ID is available
var replayId = JavaSdk.ScopesAdapter.Instance?.Options?.ReplayController?.ReplayId?.ToSentryId();
return (replayId is { } id && id != SentryId.Empty) ? id : null;
#elif __IOS__
string? nativeId = null;
SentryCocoaSdk.ConfigureScope(scope => nativeId = scope.ReplayId);
return (nativeId is { } id) ? SentryId.Parse(id) : null;
#else
return null;
#endif
Expand Down
66 changes: 66 additions & 0 deletions src/Sentry/Platforms/Cocoa/SentryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,72 @@ 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>
/// 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;

/// <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().
Expand Down
17 changes: 17 additions & 0 deletions src/Sentry/Platforms/Cocoa/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,23 @@ 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 SDKt
options.AutoSessionTracking = false;
nativeOptions.EnableAutoSessionTracking = true;
Copy link
Collaborator Author

@jamescrosswell jamescrosswell Oct 28, 2025

Choose a reason for hiding this comment

The 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:

var hasTerminalException = processedEvent.HasTerminalException();
if (hasTerminalException)
{
// Event contains a terminal exception -> end session as crashed
_options.LogDebug("Ending session as Crashed, due to unhandled exception.");
scope.SessionUpdate = _sessionManager.EndSession(SessionEndStatus.Crashed);
}
else if (processedEvent.HasException())
{
// Event contains a non-terminal exception -> report error
// (this might return null if the session has already reported errors before)
scope.SessionUpdate = _sessionManager.ReportError();
}

... or this:

// Start a new session
try
{
var sessionUpdate = _sessionManager.StartSession();
if (sessionUpdate is not null)
{
CaptureSession(sessionUpdate);
}
}

If the CocoaSdk owns the session, do we still need to be able to start/stop sessions from the .NET SDK?


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;
nativeOptions.SessionReplay = cocoaReplayOptions;
}

// Set hybrid SDK name
SentryCocoaHybridSdk.SetSdkName("sentry.cocoa.dotnet");

Expand Down
Loading