From c3958544487507da31b8461b05e0be943682d4d2 Mon Sep 17 00:00:00 2001 From: GitHub Date: Mon, 23 Mar 2026 03:51:08 +0000 Subject: [PATCH 1/4] chore: update modules/sentry-cocoa.properties to 9.8.0 --- modules/sentry-cocoa.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sentry-cocoa.properties b/modules/sentry-cocoa.properties index 7f9724515f..c953972b29 100644 --- a/modules/sentry-cocoa.properties +++ b/modules/sentry-cocoa.properties @@ -1,2 +1,2 @@ -version = 9.7.0 +version = 9.8.0 repo = https://github.com/getsentry/sentry-cocoa From 88749db9b02fef1e4a756705f883e7300d108914 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Mon, 23 Mar 2026 20:32:51 +1300 Subject: [PATCH 2/4] Update API definitions --- src/Sentry.Bindings.Cocoa/ApiDefinitions.cs | 19 ++++++++++++++----- src/Sentry.Bindings.Cocoa/StructsAndEnums.cs | 8 ++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs index 45cc7c5665..860006406a 100644 --- a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs +++ b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs @@ -213,8 +213,8 @@ interface SentryBreadcrumb : SentrySerializable [NullAllowed, Export("origin")] string Origin { get; set; } - // @property (nonatomic, strong) NSDictionary * _Nullable data; - [NullAllowed, Export("data", ArgumentSemantic.Strong)] + // @property (copy, nonatomic) NSDictionary * _Nullable data; + [NullAllowed, Export("data", ArgumentSemantic.Copy)] NSDictionary Data { get; set; } // -(instancetype _Nonnull)initWithLevel:(SentryLevel)level category:(NSString * _Nonnull)category; @@ -1746,10 +1746,14 @@ interface SentryOptions [NullAllowed, Export("beforeCaptureViewHierarchy", ArgumentSemantic.Copy)] SentryBeforeCaptureScreenshotCallback BeforeCaptureViewHierarchy { get; set; } - // @property (copy, nonatomic) SentryOnCrashedLastRunCallback _Nullable onCrashedLastRun; - [NullAllowed, Export("onCrashedLastRun", ArgumentSemantic.Copy)] + // @property (copy, nonatomic) SWIFT_DEPRECATED_MSG("Use onLastRunStatusDetermined instead, which is called regardless of whether the app crashed.") SentryOnCrashedLastRunCallback onCrashedLastRun __attribute__((deprecated("Use onLastRunStatusDetermined instead, which is called regardless of whether the app crashed."))); + [Export("onCrashedLastRun", ArgumentSemantic.Copy)] SentryOnCrashedLastRunCallback OnCrashedLastRun { get; set; } + // @property (copy, nonatomic) void (^ _Nullable)(enum SentryLastRunStatus, SentryEvent * _Nullable) onLastRunStatusDetermined; + [NullAllowed, Export("onLastRunStatusDetermined", ArgumentSemantic.Copy)] + Action OnLastRunStatusDetermined { get; set; } + // @property (nonatomic, strong) NSNumber * _Nullable sampleRate; [NullAllowed, Export("sampleRate", ArgumentSemantic.Strong)] NSNumber SampleRate { get; set; } @@ -2736,11 +2740,16 @@ interface SentrySDK [Export("configureScope:")] void ConfigureScope(Action callback); - // @property (readonly, nonatomic, class) BOOL crashedLastRun; + // @property (readonly, nonatomic, class) BOOL crashedLastRun __attribute__((deprecated("Use lastRunStatus instead, which distinguishes between 'did not crash' and 'unknown'."))); [Static] [Export("crashedLastRun")] bool CrashedLastRun { get; } + // @property (readonly, nonatomic, class) enum SentryLastRunStatus lastRunStatus; + [Static] + [Export("lastRunStatus")] + SentryLastRunStatus LastRunStatus { get; } + // @property (readonly, nonatomic, class) BOOL detectedStartUpCrash; [Static] [Export("detectedStartUpCrash")] diff --git a/src/Sentry.Bindings.Cocoa/StructsAndEnums.cs b/src/Sentry.Bindings.Cocoa/StructsAndEnums.cs index fcab4e8869..67e8a8a1ae 100644 --- a/src/Sentry.Bindings.Cocoa/StructsAndEnums.cs +++ b/src/Sentry.Bindings.Cocoa/StructsAndEnums.cs @@ -122,6 +122,14 @@ internal enum SentryHttpStatusCode : long InternalServerError = 500 } +[Native] +internal enum SentryLastRunStatus : long +{ + Unknown = 0, + DidNotCrash = 1, + DidCrash = 2 +} + [Native] internal enum SentryLogLevel : long { From 89094caac23c05a633ab07fb9004971df789907a Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Tue, 24 Mar 2026 12:13:44 +1300 Subject: [PATCH 3/4] Fixed nullability --- src/Sentry.Bindings.Cocoa/ApiDefinitions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs index 860006406a..f00a6f2df1 100644 --- a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs +++ b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs @@ -1747,12 +1747,12 @@ interface SentryOptions SentryBeforeCaptureScreenshotCallback BeforeCaptureViewHierarchy { get; set; } // @property (copy, nonatomic) SWIFT_DEPRECATED_MSG("Use onLastRunStatusDetermined instead, which is called regardless of whether the app crashed.") SentryOnCrashedLastRunCallback onCrashedLastRun __attribute__((deprecated("Use onLastRunStatusDetermined instead, which is called regardless of whether the app crashed."))); - [Export("onCrashedLastRun", ArgumentSemantic.Copy)] + [NullAllowed, Export("onCrashedLastRun", ArgumentSemantic.Copy)] SentryOnCrashedLastRunCallback OnCrashedLastRun { get; set; } // @property (copy, nonatomic) void (^ _Nullable)(enum SentryLastRunStatus, SentryEvent * _Nullable) onLastRunStatusDetermined; [NullAllowed, Export("onLastRunStatusDetermined", ArgumentSemantic.Copy)] - Action OnLastRunStatusDetermined { get; set; } + Action OnLastRunStatusDetermined { get; set; } // @property (nonatomic, strong) NSNumber * _Nullable sampleRate; [NullAllowed, Export("sampleRate", ArgumentSemantic.Strong)] From 66aab89904f1272dc78ebecdd95254c6a3d83116 Mon Sep 17 00:00:00 2001 From: James Crosswell Date: Tue, 24 Mar 2026 17:52:31 +1300 Subject: [PATCH 4/4] Fixed script to avoid dirty check failure --- AGENTS.md | 1 + scripts/patch-cocoa-bindings.cs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 100a221a9c..95753305d0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -87,6 +87,7 @@ scripts/ # Build and maintenance scripts - **macOS only**. Requires Xcode. - `Sentry.Bindings.Cocoa` wraps the native Cocoa SDK. - Device tests run in CI only. +- `src/Sentry.Bindings.Cocoa/ApiDefinitions.cs` and `StructsAndEnums.cs` are **auto-generated** — do not edit them directly. All changes must go in `scripts/patch-cocoa-bindings.cs` and be applied by running `scripts/generate-cocoa-bindings.ps1`. ### MAUI - Requires MAUI workloads: `sudo dotnet workload restore` (macOS/Linux) or `dotnet workload restore` (Windows). diff --git a/scripts/patch-cocoa-bindings.cs b/scripts/patch-cocoa-bindings.cs index 6e1323686d..a6639fe8a2 100644 --- a/scripts/patch-cocoa-bindings.cs +++ b/scripts/patch-cocoa-bindings.cs @@ -77,6 +77,10 @@ .RemoveAttribute("PrivateSentrySDKOnly", "CaptureViewHierarchy", "NullAllowed") .WithAttribute("PrivateSentrySDKOnly", "CaptureScreenshots", "return: NullAllowed") .WithAttribute("PrivateSentrySDKOnly", "CaptureViewHierarchy", "return: NullAllowed") + // Fix nullable property attributes + .WithPropertyAttribute("SentryOptions", "OnCrashedLastRun", "NullAllowed") + // Fix nullable generic type arguments + .ChangePropertyType("SentryOptions", "OnLastRunStatusDetermined", "Action") // For PrivateApiDefinitions.cs .WithModifier("SentryScope", "partial") // error CS0246: The type or namespace name 'iOS' could not be found @@ -309,6 +313,30 @@ public static CompilationUnitSyntax WithAttribute( return root.ReplaceNodes(nodes, (node, _) => node.WithAttribute(attribute)); } + public static CompilationUnitSyntax WithPropertyAttribute( + this CompilationUnitSyntax root, + string type, + string name, + string attribute) + { + var nodes = root.DescendantNodes() + .OfType() + .Where(node => node.Identifier.Matches(name) && node.HasParent(type) && !node.HasAttribute(attribute)); + return root.ReplaceNodes(nodes, (node, _) => + { + var newAttr = SyntaxFactory.Attribute(SyntaxFactory.IdentifierName(attribute)); + if (node.AttributeLists.Count > 0) + { + // Prepend into the first existing attribute list (e.g. [NullAllowed, Export(...)]) + var first = node.AttributeLists[0]; + var prepended = first.WithAttributes( + SyntaxFactory.SeparatedList(new[] { newAttr }.Concat(first.Attributes))); + return node.WithAttributeLists(node.AttributeLists.Replace(first, prepended)); + } + return (PropertyDeclarationSyntax)node.WithAttribute(attribute); + }); + } + public static CompilationUnitSyntax AsInternal( this CompilationUnitSyntax root, string name,