diff --git a/.generated.NoMobile.slnx b/.generated.NoMobile.slnx
index d6fd58d14f..babff9ea4d 100644
--- a/.generated.NoMobile.slnx
+++ b/.generated.NoMobile.slnx
@@ -54,7 +54,6 @@
-
diff --git a/.github/workflows/device-tests-android.yml b/.github/workflows/device-tests-android.yml
index 5a5fe3c5c0..ec35ae3f12 100644
--- a/.github/workflows/device-tests-android.yml
+++ b/.github/workflows/device-tests-android.yml
@@ -37,7 +37,6 @@ on:
- 'lib/sentry-android-supplemental/**'
- 'modules/sentry-native/**'
- 'modules/sentry-cocoa/**'
- - 'modules/sentry-cocoa.properties'
# Build configuration (affects all builds)
- 'global.json'
- 'Directory.Build.props'
diff --git a/.github/workflows/device-tests-ios.yml b/.github/workflows/device-tests-ios.yml
index 7d7bfdb0b1..749827140b 100644
--- a/.github/workflows/device-tests-ios.yml
+++ b/.github/workflows/device-tests-ios.yml
@@ -37,7 +37,6 @@ on:
- 'lib/sentry-android-supplemental/**'
- 'modules/sentry-native/**'
- 'modules/sentry-cocoa/**'
- - 'modules/sentry-cocoa.properties'
# Build configuration (affects all builds)
- 'global.json'
- 'Directory.Build.props'
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fc60035091..7553b5caad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -194,27 +194,26 @@ should be updated from the main branch and the `modules/make-internal.sh` script
should reference the most recent commit on the `internal` branch of Ben.Demystifier then (functionally identical to the
main branch - the only difference being the changes to member visibility).
-## Local Sentry Cocoa SDK checkout
+## Sentry Cocoa SDK checkout
-By default, `Sentry.Bindings.Cocoa` downloads a pre-built Sentry Cocoa SDK from
-GitHub Releases. The version is specified in `modules/sentry-cocoa.properties`.
+`Sentry.Bindings.Cocoa` always builds the Sentry Cocoa SDK from source, from the
+[getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa/) submodule at
+`modules/sentry-cocoa` (`scripts/build-sentry-cocoa.sh`, invoked automatically by
+the build). Pre-built release artifacts can't be used: the `SentryObjC` hybrid-API
+frameworks are only published as self-contained bundles that would embed a second
+copy of the SDK alongside `Sentry.framework` (see
+[#5331](https://github.com/getsentry/sentry-dotnet/issues/5331)).
-If you want to build an unreleased Sentry Cocoa SDK version from source instead,
-replace the pre-built SDK with [getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa/)
-by cloning it into the `modules/sentry-cocoa` directory:
+To build against a different Cocoa SDK version, check out the desired ref in the
+submodule **and stage it** — the solution build automatically runs
+`git submodule update` (see `before.Sentry.sln.targets`), which reverts the
+submodule to the pinned commit unless the index already records your ref:
```sh
-$ rm -rf modules/sentry-cocoa
-$ gh repo clone getsentry/sentry-cocoa modules/sentry-cocoa
-$ dotnet build ... # uses modules/sentry-cocoa as is
-```
-
-To switch back to the pre-built SDK, delete the `modules/sentry-cocoa` directory
-and let the next build download the pre-built SDK again:
-
-```sh
-$ rm -rf modules/sentry-cocoa
-$ dotnet build ... # downloads pre-built Cocoa SDK into modules/sentry-cocoa
+$ git -C modules/sentry-cocoa fetch origin
+$ git -C modules/sentry-cocoa checkout
+$ git add modules/sentry-cocoa # otherwise the build restores the pinned commit
+$ dotnet build ... # rebuilds the Cocoa SDK from the new ref
```
## Local Sentry Android SDK checkout
diff --git a/Sentry.slnx b/Sentry.slnx
index d6fd58d14f..babff9ea4d 100644
--- a/Sentry.slnx
+++ b/Sentry.slnx
@@ -54,7 +54,6 @@
-
diff --git a/integration-test/cli.Tests.ps1 b/integration-test/cli.Tests.ps1
index d03d5c235a..e02e69b66d 100644
--- a/integration-test/cli.Tests.ps1
+++ b/integration-test/cli.Tests.ps1
@@ -191,7 +191,9 @@ Describe 'MAUI ()' -ForEach @(
'Microsoft.Maui.Essentials.pdb',
'Microsoft.Maui.Graphics.pdb',
'Microsoft.Maui.pdb',
- 'Sentry'
+ 'Sentry',
+ 'SentryObjC',
+ 'SentryObjCCompat'
)
# The specific number of debug information files seems to change with different SDK - so we just check for non-zero
$nonZeroNumberRegex = '[1-9][0-9]*';
diff --git a/scripts/build-sentry-cocoa.sh b/scripts/build-sentry-cocoa.sh
index f3ef2b7558..4c78b66728 100755
--- a/scripts/build-sentry-cocoa.sh
+++ b/scripts/build-sentry-cocoa.sh
@@ -1,6 +1,11 @@
#!/bin/bash
set -euo pipefail
+# Include this script's own hash in the build stamp so cached output is rebuilt whenever the
+# recipe changes (e.g. when new frameworks are added to the build), not just when the
+# sentry-cocoa submodule moves. Mirrors the cache key used for sentry-native in CI.
+script_checksum=$(shasum -a 256 "$0" | cut -d ' ' -f 1)
+
pushd "$(dirname "$0")" >/dev/null
cd ../modules/sentry-cocoa
@@ -24,8 +29,8 @@ while ! ln "$TMP_FILE" "$PID_FILE" 2>/dev/null; do
done
rm -f "$TMP_FILE"
-current_sha=$(git rev-parse HEAD)
-if [[ -f Carthage/.built-from-sha ]] && [[ "$(cat Carthage/.built-from-sha)" == "$current_sha" ]]; then
+build_stamp="$(git rev-parse HEAD) $script_checksum"
+if [[ -f Carthage/.built-from-sha ]] && [[ "$(cat Carthage/.built-from-sha)" == "$build_stamp" ]]; then
popd >/dev/null
exit 0
fi
@@ -67,6 +72,38 @@ xcodebuild -create-xcframework \
-output ./Carthage/Build-ios/Sentry.xcframework
echo "::endgroup::"
+# The SentryObjC scheme adds the structured hybrid API (SentryObjCSDK.internal), which the .NET
+# bindings use in place of the deprecated PrivateSentrySDKOnly. It produces two thin frameworks -
+# SentryObjC and SentryObjCCompat - that dynamically link the Sentry.framework built above (they do
+# not embed their own copy of the SDK), so we bundle them alongside Sentry.xcframework. We build
+# these from source rather than downloading the pre-built SentryObjC-Dynamic.xcframework because
+# that release artifact is self-contained (it embeds the whole SDK) and would duplicate Sentry.
+echo "::group::Building SentryObjC for iOS and iOS simulator"
+xcodebuild archive -project Sentry.xcodeproj \
+ -scheme SentryObjC \
+ -configuration Release \
+ -sdk "$ios_sdk" \
+ -archivePath ./Carthage/output-objc-ios.xcarchive \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
+ GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1'
+./scripts/remove-architectures.sh ./Carthage/output-objc-ios.xcarchive arm64e
+xcodebuild archive -project Sentry.xcodeproj \
+ -scheme SentryObjC \
+ -configuration Release \
+ -sdk "$ios_simulator_sdk" \
+ -archivePath ./Carthage/output-objc-iossimulator.xcarchive \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
+ GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1'
+for fw in SentryObjC SentryObjCCompat; do
+ xcodebuild -create-xcframework \
+ -framework "./Carthage/output-objc-ios.xcarchive/Products/Library/Frameworks/$fw.framework" \
+ -framework "./Carthage/output-objc-iossimulator.xcarchive/Products/Library/Frameworks/$fw.framework" \
+ -output "./Carthage/Build-ios/$fw.xcframework"
+done
+echo "::endgroup::"
+
# Separately, build for Mac Catalyst
echo "::group::Building sentry-cocoa for Mac Catalyst"
xcodebuild archive -project Sentry.xcodeproj \
@@ -83,15 +120,41 @@ xcodebuild -create-xcframework \
-output ./Carthage/Build-maccatalyst/Sentry.xcframework
echo "::endgroup::"
+echo "::group::Building SentryObjC for Mac Catalyst"
+xcodebuild archive -project Sentry.xcodeproj \
+ -scheme SentryObjC \
+ -configuration Release \
+ -destination 'generic/platform=macOS,variant=Mac Catalyst' \
+ -archivePath ./Carthage/output-objc-maccatalyst.xcarchive \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
+ GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1'
+./scripts/remove-architectures.sh ./Carthage/output-objc-maccatalyst.xcarchive arm64e
+for fw in SentryObjC SentryObjCCompat; do
+ xcodebuild -create-xcframework \
+ -framework "./Carthage/output-objc-maccatalyst.xcarchive/Products/Library/Frameworks/$fw.framework" \
+ -output "./Carthage/Build-maccatalyst/$fw.xcframework"
+done
+echo "::endgroup::"
+
+# Xcode embeds each framework's dynamic dependencies under .framework/Frameworks/ (e.g.
+# SentryObjC.framework/Frameworks/SentryObjCCompat.framework/Frameworks/Sentry.framework). We bundle
+# Sentry, SentryObjCCompat and SentryObjC as separate NativeReferences - each embedded into the
+# consuming app - so those nested copies are redundant, and their deep paths blow past NuGet's path
+# length limit (NU5123). To fix that, we strip them. The frameworks resolve each other via @rpath at the app level instead/anyway.
+find Carthage/Build-*/SentryObjC*.xcframework -type d -name Frameworks -prune -exec rm -rf {} +
+
# Copy headers - used for generating bindings
mkdir Carthage/Headers
find Carthage/Build-ios/Sentry.xcframework/ios-arm64 -name '*.h' -exec cp {} Carthage/Headers \;
+find Carthage/Build-ios/SentryObjC.xcframework/ios-arm64 -name '*.h' -exec cp {} Carthage/Headers \;
+find Carthage/Build-ios/SentryObjCCompat.xcframework/ios-arm64 -name '*.h' -exec cp {} Carthage/Headers \;
# Remove anything we don't want to bundle in the nuget package.
find Carthage/Build* \( -name Headers -o -name PrivateHeaders -o -name Modules \) -exec rm -rf {} +
rm -rf Carthage/output-*
-echo "$current_sha" > Carthage/.built-from-sha
+echo "$build_stamp" > Carthage/.built-from-sha
echo ""
popd >/dev/null
diff --git a/scripts/generate-cocoa-bindings.ps1 b/scripts/generate-cocoa-bindings.ps1
index 1c102f3b17..e1e368d73a 100644
--- a/scripts/generate-cocoa-bindings.ps1
+++ b/scripts/generate-cocoa-bindings.ps1
@@ -6,18 +6,9 @@ $PSNativeCommandUseErrorActionPreference = $true
$RootPath = (Get-Item $PSScriptRoot).Parent.FullName
$CocoaSdkPath = "$RootPath/modules/sentry-cocoa"
-if (Test-Path "$CocoaSdkPath/.git")
-{
- # Cocoa SDK cloned to modules/sentry-cocoa for local development
- $HeadersPath = "$CocoaSdkPath/Carthage/Headers"
- $PrivateHeadersPath = "$CocoaSdkPath/Carthage/Headers"
-}
-else
-{
- # Cocoa SDK downloaded from GitHub releases and extracted into modules/sentry-cocoa
- $HeadersPath = "$CocoaSdkPath/Sentry.framework/Headers"
- $PrivateHeadersPath = "$CocoaSdkPath/Sentry.framework/PrivateHeaders"
-}
+# The Cocoa SDK is built from source from the modules/sentry-cocoa submodule;
+# build-sentry-cocoa.sh copies the headers here.
+$HeadersPath = "$CocoaSdkPath/Carthage/Headers"
$BindingsPath = "$RootPath/src/Sentry.Bindings.Cocoa"
$BackupPath = "$BindingsPath/obj/_unpatched"
@@ -164,12 +155,18 @@ else
}
# Generate bindings
+# The SentryObjC*.h headers expose the structured hybrid API (SentryObjCSDK.internal)
Write-Output 'Generating bindings with Objective Sharpie.'
sharpie bind -sdk $iPhoneSdkVersion `
-scope "$CocoaSdkPath" `
"$HeadersPath/Sentry.h" `
"$HeadersPath/Sentry-Swift.h" `
- "$HeadersPath/PrivateSentrySDKOnly.h" `
+ "$HeadersPath/SentryObjCSDK.h" `
+ "$HeadersPath/SentryObjCInternalApi.h" `
+ "$HeadersPath/SentryObjCInternalSdkApi.h" `
+ "$HeadersPath/SentryObjCInternalProfilingApi.h" `
+ "$HeadersPath/SentryObjCId.h" `
+ "$HeadersPath/SentryObjCSpanId.h" `
-o $BindingsPath `
-c -Wno-objc-property-no-attribute `
-F"$iPhoneSdkPath/System/Library/SubFrameworks" # needed for UIUtilities.framework in Xcode 26+
diff --git a/scripts/patch-cocoa-bindings.cs b/scripts/patch-cocoa-bindings.cs
index 6d6eb801e7..b9edea2de5 100644
--- a/scripts/patch-cocoa-bindings.cs
+++ b/scripts/patch-cocoa-bindings.cs
@@ -57,7 +57,6 @@
.PropertyToMethod("Sentry*", "Serialize")
.PropertyToMethod("SentrySpan", "ToTraceHeader")
.PropertyToMethod("SentryTraceContext", "ToBaggage")
- .PropertyToMethod("PrivateSentrySDKOnly", "Capture*")
// Verify the rest
.VerifyProperty("*Sentry*", "*", "MethodToProperty") // TODO: replace broad patterns with one-by-one verification
.VerifyProperty("SentryOptions", "*Targets", "StronglyTypedNSArray")
@@ -81,11 +80,6 @@
.WithAttribute("SentryBeforeBreadcrumbCallback", "return: NullAllowed")
.WithAttribute("SentryBeforeSendEventCallback", "return: NullAllowed")
.WithAttribute("SentryTracesSamplerCallback", "return: NullAllowed")
- // Fix nullable return attributes
- .RemoveAttribute("PrivateSentrySDKOnly", "CaptureScreenshots", "NullAllowed")
- .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
@@ -104,10 +98,6 @@
.RemoveMethod("Sentry*", "CopyWithZone")
// error CS0111: Type 'SentryAttribute' already defines a member called 'Constructor' with the same parameter types
.RemoveMethod("SentryLog", "SetAttribute")
- // SentryEnvelope* is not whitelisted
- .RemoveMethod("PrivateSentrySDKOnly", "CaptureEnvelope")
- .RemoveMethod("PrivateSentrySDKOnly", "EnvelopeWithData")
- .RemoveMethod("PrivateSentrySDKOnly", "StoreEnvelope")
// SentryLoggerDelegate and SentryCurrentDateProvider are not whitelisted
.RemoveMethod("SentryLogger", "Constructor")
// SentryAppStartMeasurement is not whitelisted
@@ -116,17 +106,24 @@
.RemoveDelegate("SentryUserFeedbackConfigurationBlock")
// error CS0114: 'SentryXxx.Description' hides inherited member 'NSObject.Description'.
.RemoveProperty("Sentry*", "Description")
- // SentryAppStartMeasurement is not whitelisted
- .RemoveProperty("PrivateSentrySDKOnly", "*AppStartMeasurement*")
// Minimize SentryDependencyContainer
.RemoveMethod("SentryDependencyContainer", "*")
.KeepProperties("SentryDependencyContainer", "SharedInstance", "DebugImageProvider")
// SentryUserFeedbackConfiguration is not whitelisted
.RemoveProperty("SentryOptions", "ConfigureUserFeedback")
.RemoveProperty("SentryOptions", "UserFeedbackConfiguration")
+ // SentryObjCSDK.internal is the entry point to the API for hybrid SDKs
+ // We only bind the `internal` accessor; every other SentryObjCSDK member references SentryObjC*
+ // types we don't whitelist.
+ .KeepProperties("SentryObjCSDK", "Internal")
+ .RemoveMethod("SentryObjCSDK", "*")
+ .KeepProperties("SentryObjCInternalApi", "Sdk", "Profiling")
+ .KeepMethods("SentryObjCInternalApi", "SetTrace", "IgnoreNextSignal")
+ // Sharpie generates enums for types the SentryObjC headers reference, but the members that used
+ // them are trimmed above - drop the dead enums
+ .RemoveEnum("SentryObjC*")
.KeepInterfaces(
"ISentryRRWebEvent",
- "PrivateSentrySDKOnly",
"SentryAttachment",
"SentryBaggage",
"SentryBreadcrumb",
@@ -155,6 +152,12 @@
"SentryMechanismContext",
"SentryMessage",
"SentryNSError",
+ "SentryObjCId",
+ "SentryObjCInternalApi",
+ "SentryObjCInternalProfilingApi",
+ "SentryObjCInternalSdkApi",
+ "SentryObjCSDK",
+ "SentryObjCSpanId",
"SentryOptions",
"SentryProfileOptions",
"SentryRedactOptions",
@@ -251,6 +254,13 @@ public static CompilationUnitSyntax RemoveClass(
return root.RemoveByPredicate(node => node.Identifier.Matches(name));
}
+ public static CompilationUnitSyntax RemoveEnum(
+ this CompilationUnitSyntax root,
+ string name)
+ {
+ return root.RemoveByPredicate(node => node.Identifier.Matches(name));
+ }
+
public static CompilationUnitSyntax RemoveDelegate(
this CompilationUnitSyntax root,
string name)
diff --git a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs
index 8b0245cfbd..f9d79d19db 100644
--- a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs
+++ b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs
@@ -1517,172 +1517,6 @@ interface SentryUser : SentrySerializable
nuint Hash { get; }
}
-// @interface PrivateSentrySDKOnly : NSObject
-[BaseType(typeof(NSObject))]
-[Internal]
-interface PrivateSentrySDKOnly
-{
-
- // +(void)setSdkName:(NSString * _Nonnull)sdkName andVersionString:(NSString * _Nonnull)versionString;
- [Static]
- [Export("setSdkName:andVersionString:")]
- void SetSdkName(string sdkName, string versionString);
-
- // +(void)setSdkName:(NSString * _Nonnull)sdkName;
- [Static]
- [Export("setSdkName:")]
- void SetSdkName(string sdkName);
-
- // +(NSString * _Nonnull)getSdkName;
- [Static]
- [Export("getSdkName")]
- string SdkName { get; }
-
- // +(NSString * _Nonnull)getSdkVersionString;
- [Static]
- [Export("getSdkVersionString")]
- string SdkVersionString { get; }
-
- // +(void)addSdkPackage:(NSString * _Nonnull)name version:(NSString * _Nonnull)version;
- [Static]
- [Export("addSdkPackage:version:")]
- void AddSdkPackage(string name, string version);
-
- // +(NSDictionary * _Nonnull)getExtraContext;
- [Static]
- [Export("getExtraContext")]
- NSDictionary ExtraContext { get; }
-
- // +(void)setTrace:(SentryId * _Nonnull)traceId spanId:(SentrySpanId * _Nonnull)spanId;
- [Static]
- [Export("setTrace:spanId:")]
- void SetTrace(SentryId traceId, SentrySpanId spanId);
-
- // +(uint64_t)startProfilerForTrace:(SentryId * _Nonnull)traceId;
- [Static]
- [Export("startProfilerForTrace:")]
- ulong StartProfilerForTrace(SentryId traceId);
-
- // +(NSMutableDictionary * _Nullable)collectProfileBetween:(uint64_t)startSystemTime and:(uint64_t)endSystemTime forTrace:(SentryId * _Nonnull)traceId;
- [Static]
- [Export("collectProfileBetween:and:forTrace:")]
- [return: NullAllowed]
- NSMutableDictionary CollectProfileBetween(ulong startSystemTime, ulong endSystemTime, SentryId traceId);
-
- // +(void)discardProfilerForTrace:(SentryId * _Nonnull)traceId;
- [Static]
- [Export("discardProfilerForTrace:")]
- void DiscardProfilerForTrace(SentryId traceId);
-
- // @property (readonly, copy, nonatomic, class) NSString * _Nonnull installationID;
- [Static]
- [Export("installationID")]
- string InstallationID { get; }
-
- // @property (readonly, copy, nonatomic, class) SentryOptions * _Nonnull options;
- [Static]
- [Export("options", ArgumentSemantic.Copy)]
- SentryOptions Options { get; }
-
- // @property (assign, nonatomic, class) BOOL framesTrackingMeasurementHybridSDKMode;
- [Static]
- [Export("framesTrackingMeasurementHybridSDKMode")]
- bool FramesTrackingMeasurementHybridSDKMode { get; set; }
-
- // @property (readonly, assign, nonatomic, class) BOOL isFramesTrackingRunning;
- [Static]
- [Export("isFramesTrackingRunning")]
- bool IsFramesTrackingRunning { get; }
-
- // @property (readonly, assign, nonatomic, class) SentryScreenFrames * _Nonnull currentScreenFrames;
- [Static]
- [Export("currentScreenFrames", ArgumentSemantic.Assign)]
- SentryScreenFrames CurrentScreenFrames { get; }
-
- // +(NSArray * _Nullable)captureScreenshots;
- [Static]
- [Export("captureScreenshots")]
- [return: NullAllowed]
- NSData[] CaptureScreenshots();
-
- // +(NSData * _Nullable)captureViewHierarchy;
- [Static]
- [Export("captureViewHierarchy")]
- [return: NullAllowed]
- NSData CaptureViewHierarchy();
-
- // +(void)setCurrentScreen:(NSString * _Nullable)screenName;
- [Static]
- [Export("setCurrentScreen:")]
- void SetCurrentScreen([NullAllowed] string screenName);
-
- // +(void)configureSessionReplayWith:(id _Nullable)breadcrumbConverter screenshotProvider:(id _Nullable)screenshotProvider;
- [Static]
- [Export("configureSessionReplayWith:screenshotProvider:")]
- void ConfigureSessionReplayWith([NullAllowed] SentryReplayBreadcrumbConverter breadcrumbConverter, [NullAllowed] SentryViewScreenshotProvider screenshotProvider);
-
- // +(void)captureReplay;
- [Static]
- [Export("captureReplay")]
- void CaptureReplay();
-
- // +(NSString * _Nullable)getReplayId;
- [Static]
- [NullAllowed, Export("getReplayId")]
- string ReplayId { get; }
-
- // +(void)addReplayIgnoreClasses:(NSArray * _Nonnull)classes;
- [Static]
- [Export("addReplayIgnoreClasses:")]
- void AddReplayIgnoreClasses(Class[] classes);
-
- // +(void)addReplayRedactClasses:(NSArray * _Nonnull)classes;
- [Static]
- [Export("addReplayRedactClasses:")]
- void AddReplayRedactClasses(Class[] classes);
-
- // +(void)setIgnoreContainerClass:(Class _Nonnull)containerClass;
- [Static]
- [Export("setIgnoreContainerClass:")]
- void SetIgnoreContainerClass(Class containerClass);
-
- // +(void)setRedactContainerClass:(Class _Nonnull)containerClass;
- [Static]
- [Export("setRedactContainerClass:")]
- void SetRedactContainerClass(Class containerClass);
-
- // +(void)setReplayTags:(NSDictionary * _Nonnull)tags;
- [Static]
- [Export("setReplayTags:")]
- void SetReplayTags(NSDictionary tags);
-
- // +(SentryUser * _Nonnull)userWithDictionary:(NSDictionary * _Nonnull)dictionary;
- [Static]
- [Export("userWithDictionary:")]
- SentryUser UserWithDictionary(NSDictionary dictionary);
-
- // +(SentryBreadcrumb * _Nonnull)breadcrumbWithDictionary:(NSDictionary * _Nonnull)dictionary;
- [Static]
- [Export("breadcrumbWithDictionary:")]
- SentryBreadcrumb BreadcrumbWithDictionary(NSDictionary dictionary);
-
- // +(SentryOptions * _Nullable)optionsWithDictionary:(NSDictionary * _Nonnull)options didFailWithError:(NSError * _Nullable * _Nullable)error;
- [Static]
- [Export("optionsWithDictionary:didFailWithError:")]
- [return: NullAllowed]
- SentryOptions OptionsWithDictionary(NSDictionary options, [NullAllowed] out NSError error);
-
- // +(void)setLogOutput:(void (^ _Nonnull)(NSString * _Nonnull))output;
- [Static]
- [Export("setLogOutput:")]
- void SetLogOutput(Action output);
-
- // +(void)ignoreNextSignal:(int)signum;
- [Static]
- [Export("ignoreNextSignal:")]
- void IgnoreNextSignal(int signum);
-}
-
// @interface SentryOptions : NSObject
[BaseType(typeof(NSObject))]
[Internal]
@@ -3024,3 +2858,135 @@ interface SentryViewScreenshotOptions : SentryRedactOptions
[DesignatedInitializer]
NativeHandle Constructor(bool enableViewRendererV2, bool enableFastViewRendering, bool maskAllText, bool maskAllImages, Class[] maskedViewClasses, Class[] unmaskedViewClasses, NSSet excludedViewClasses, NSSet includedViewClasses);
}
+
+// @interface SentryObjCSDK : NSObject
+[BaseType(typeof(NSObject))]
+[Internal]
+interface SentryObjCSDK
+{
+
+ // @property (readonly, nonatomic, class) SentryObjCInternalApi * _Nonnull internal;
+ [Static]
+ [Export("internal")]
+ SentryObjCInternalApi Internal { get; }
+}
+
+// @interface SentryObjCInternalApi : NSObject
+[BaseType(typeof(NSObject))]
+[DisableDefaultCtor]
+[Internal]
+interface SentryObjCInternalApi
+{
+ // @property (readonly, nonatomic) SentryObjCInternalSdkApi * _Nonnull sdk;
+ [Export("sdk")]
+ SentryObjCInternalSdkApi Sdk { get; }
+
+ // @property (readonly, nonatomic) SentryObjCInternalProfilingApi * _Nonnull profiling;
+ [Export("profiling")]
+ SentryObjCInternalProfilingApi Profiling { get; }
+
+ // -(void)setTrace:(SentryObjCId * _Nonnull)traceId spanId:(SentryObjCSpanId * _Nonnull)spanId;
+ [Export("setTrace:spanId:")]
+ void SetTrace(SentryObjCId traceId, SentryObjCSpanId spanId);
+
+ // -(void)ignoreNextSignal:(int)signum;
+ [Export("ignoreNextSignal:")]
+ void IgnoreNextSignal(int signum);
+}
+
+// @interface SentryObjCInternalSdkApi : NSObject
+[BaseType(typeof(NSObject))]
+[DisableDefaultCtor]
+[Internal]
+interface SentryObjCInternalSdkApi
+{
+ // @property (copy, nonatomic) NSString * _Nonnull name;
+ [Export("name")]
+ string Name { get; set; }
+
+ // @property (copy, nonatomic) NSString * _Nonnull versionString;
+ [Export("versionString")]
+ string VersionString { get; set; }
+
+ // -(void)setName:(NSString * _Nonnull)name version:(NSString * _Nonnull)version;
+ [Export("setName:version:")]
+ void SetName(string name, string version);
+
+ // -(void)addPackageName:(NSString * _Nonnull)name version:(NSString * _Nonnull)version;
+ [Export("addPackageName:version:")]
+ void AddPackageName(string name, string version);
+
+ // @property (readonly, copy, nonatomic) NSDictionary * _Nonnull extraContext;
+ [Export("extraContext", ArgumentSemantic.Copy)]
+ NSDictionary ExtraContext { get; }
+
+ // @property (readonly, copy, nonatomic) NSString * _Nonnull installationID;
+ [Export("installationID")]
+ string InstallationID { get; }
+}
+
+// @interface SentryObjCInternalProfilingApi : NSObject
+[BaseType(typeof(NSObject))]
+[DisableDefaultCtor]
+[Internal]
+interface SentryObjCInternalProfilingApi
+{
+ // -(uint64_t)startFor:(SentryObjCId * _Nonnull)traceId;
+ [Export("startFor:")]
+ ulong StartFor(SentryObjCId traceId);
+
+ // -(NSDictionary * _Nullable)collectBetweenStartTime:(uint64_t)startTime andEndTime:(uint64_t)endTime forTraceId:(SentryObjCId * _Nonnull)traceId;
+ [Export("collectBetweenStartTime:andEndTime:forTraceId:")]
+ [return: NullAllowed]
+ NSDictionary CollectBetweenStartTime(ulong startTime, ulong endTime, SentryObjCId traceId);
+
+ // -(void)discardFor:(SentryObjCId * _Nonnull)traceId;
+ [Export("discardFor:")]
+ void DiscardFor(SentryObjCId traceId);
+}
+
+// @interface SentryObjCId : NSObject
+[BaseType(typeof(NSObject))]
+[Internal]
+interface SentryObjCId
+{
+ // @property (readonly, copy, nonatomic) NSString * _Nonnull sentryIdString;
+ [Export("sentryIdString")]
+ string SentryIdString { get; }
+
+ // @property (readonly, nonatomic, strong, class) SentryObjCId * _Nonnull empty;
+ [Static]
+ [Export("empty", ArgumentSemantic.Strong)]
+ SentryObjCId Empty { get; }
+
+ // -(instancetype _Nonnull)initWithUuid:(NSUUID * _Nonnull)uuid;
+ [Export("initWithUuid:")]
+ NativeHandle Constructor(NSUuid uuid);
+
+ // -(instancetype _Nonnull)initWithUUIDString:(NSString * _Nonnull)uuidString;
+ [Export("initWithUUIDString:")]
+ NativeHandle Constructor(string uuidString);
+}
+
+// @interface SentryObjCSpanId : NSObject
+[BaseType(typeof(NSObject))]
+[Internal]
+interface SentryObjCSpanId
+{
+ // @property (readonly, copy, nonatomic) NSString * _Nonnull sentrySpanIdString;
+ [Export("sentrySpanIdString")]
+ string SentrySpanIdString { get; }
+
+ // @property (readonly, nonatomic, strong, class) SentryObjCSpanId * _Nonnull empty;
+ [Static]
+ [Export("empty", ArgumentSemantic.Strong)]
+ SentryObjCSpanId Empty { get; }
+
+ // -(instancetype _Nonnull)initWithUuid:(NSUUID * _Nonnull)uuid;
+ [Export("initWithUuid:")]
+ NativeHandle Constructor(NSUuid uuid);
+
+ // -(instancetype _Nonnull)initWithValue:(NSString * _Nonnull)value;
+ [Export("initWithValue:")]
+ NativeHandle Constructor(string value);
+}
diff --git a/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj b/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj
index 96bc4b2d0c..6f23ff8266 100644
--- a/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj
+++ b/src/Sentry.Bindings.Cocoa/Sentry.Bindings.Cocoa.csproj
@@ -8,22 +8,19 @@
true
.NET Bindings for the Sentry Cocoa SDK
..\..\modules\sentry-cocoa\
- $(MSBuildThisFileDirectory)..\..\modules\sentry-cocoa.properties
- $(SentryCocoaCache)Sentry.framework\
$(NoWarn);CS0108
-
-
- $([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(SentryCocoaProperties)')), 'version\s*=\s*([^\s]+)').Groups[1].Value)
- $(SentryCocoaCache)Sentry-$(SentryCocoaVersion).xcframework
- $(SentryCocoaProperties);../../scripts/generate-cocoa-bindings.ps1;$(SentryCocoaFrameworkHeaders)**/*.h
-
-
-
+
$(SentryCocoaCache)Carthage\Build-$(TargetPlatformIdentifier)\Sentry.xcframework
+
+ $(SentryCocoaCache)Carthage\Build-$(TargetPlatformIdentifier)\SentryObjC.xcframework
+ $(SentryCocoaCache)Carthage\Build-$(TargetPlatformIdentifier)\SentryObjCCompat.xcframework
../../scripts/generate-cocoa-bindings.ps1;$(SentryCocoaCache)Carthage/.built-from-sha;$(SentryCocoaCache)Carthage/**/*.h
$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory), $(SentryCocoaCache).git))
@@ -54,6 +51,8 @@
+
+
@@ -66,44 +65,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
@@ -135,8 +100,7 @@
Condition="$([MSBuild]::IsOSPlatform('OSX'))" />
-
-
+
@@ -152,15 +116,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/Sentry.Bindings.Cocoa/buildTransitive/Sentry.Bindings.Cocoa.targets b/src/Sentry.Bindings.Cocoa/buildTransitive/Sentry.Bindings.Cocoa.targets
index 4b74ad10fe..fcedf5b1b7 100644
--- a/src/Sentry.Bindings.Cocoa/buildTransitive/Sentry.Bindings.Cocoa.targets
+++ b/src/Sentry.Bindings.Cocoa/buildTransitive/Sentry.Bindings.Cocoa.targets
@@ -45,7 +45,9 @@
-->
-
+
+
diff --git a/src/Sentry/Platforms/Cocoa/CocoaProfiler.cs b/src/Sentry/Platforms/Cocoa/CocoaProfiler.cs
index 3bbed89c7b..98e368357f 100644
--- a/src/Sentry/Platforms/Cocoa/CocoaProfiler.cs
+++ b/src/Sentry/Platforms/Cocoa/CocoaProfiler.cs
@@ -9,12 +9,12 @@ internal class CocoaProfiler : ITransactionProfiler
{
private readonly SentryOptions _options;
private readonly SentryId _traceId;
- private readonly CocoaSdk.SentryId _cocoaTraceId;
+ private readonly CocoaSdk.SentryObjCId _cocoaTraceId;
private readonly ulong _startTimeNs;
private ulong _endTimeNs;
private readonly SentryStopwatch _stopwatch;
- public CocoaProfiler(SentryOptions options, ulong startTimeNs, SentryId traceId, CocoaSdk.SentryId cocoaTraceId)
+ public CocoaProfiler(SentryOptions options, ulong startTimeNs, SentryId traceId, CocoaSdk.SentryObjCId cocoaTraceId)
{
_stopwatch = SentryStopwatch.StartNew();
_options = options;
@@ -36,14 +36,17 @@ public void Finish()
public ISerializable? Collect(SentryTransaction transaction)
{
- var payload = SentryCocoaHybridSdk.CollectProfileBetween(_startTimeNs, _endTimeNs, _cocoaTraceId);
- if (payload is null)
+ var collected = SentryCocoaHybridSdk.Internal.Profiling.CollectBetweenStartTime(_startTimeNs, _endTimeNs, _cocoaTraceId);
+ if (collected is null)
{
_options.LogWarning("Trace {0} collected profile payload is null", _traceId);
return null;
}
_options.LogDebug("Trace {0} profile payload collected", _traceId);
+ // The SentryObjCSDK.internal profiling API returns an immutable NSDictionary, so copy it before mutating below.
+ var payload = (NSMutableDictionary)collected.MutableCopy();
+
var payloadTx = payload["transaction"]?.MutableCopy() as NSMutableDictionary;
if (payloadTx is null)
{
diff --git a/src/Sentry/Platforms/Cocoa/CocoaProfilerFactory.cs b/src/Sentry/Platforms/Cocoa/CocoaProfilerFactory.cs
index 2d49446bdd..246ad5b516 100644
--- a/src/Sentry/Platforms/Cocoa/CocoaProfilerFactory.cs
+++ b/src/Sentry/Platforms/Cocoa/CocoaProfilerFactory.cs
@@ -15,8 +15,8 @@ internal CocoaProfilerFactory(SentryOptions options)
///
public ITransactionProfiler? Start(ITransactionTracer tracer, CancellationToken cancellationToken)
{
- var traceId = tracer.TraceId.ToCocoaSentryId();
- var startTime = SentryCocoaHybridSdk.StartProfilerForTrace(traceId);
+ var traceId = tracer.TraceId.ToCocoaObjCId();
+ var startTime = SentryCocoaHybridSdk.Internal.Profiling.StartFor(traceId);
return new CocoaProfiler(_options, startTime, tracer.TraceId, traceId);
}
}
diff --git a/src/Sentry/Platforms/Cocoa/CocoaScopeObserver.cs b/src/Sentry/Platforms/Cocoa/CocoaScopeObserver.cs
index 46f8aebf5e..98746e5f15 100644
--- a/src/Sentry/Platforms/Cocoa/CocoaScopeObserver.cs
+++ b/src/Sentry/Platforms/Cocoa/CocoaScopeObserver.cs
@@ -112,7 +112,7 @@ public void SetTrace(SentryId traceId, SpanId parentSpanId)
{
try
{
- SentryCocoaHybridSdk.SetTrace(traceId.ToCocoaSentryId(), parentSpanId.ToCocoaSpanId());
+ SentryCocoaHybridSdk.Internal.SetTrace(traceId.ToCocoaObjCId(), parentSpanId.ToCocoaObjCSpanId());
}
finally
{
diff --git a/src/Sentry/Platforms/Cocoa/Extensions/MiscExtensions.cs b/src/Sentry/Platforms/Cocoa/Extensions/MiscExtensions.cs
index 777d09caf1..c23b5bf8d3 100644
--- a/src/Sentry/Platforms/Cocoa/Extensions/MiscExtensions.cs
+++ b/src/Sentry/Platforms/Cocoa/Extensions/MiscExtensions.cs
@@ -4,9 +4,11 @@ internal static class MiscExtensions
{
public static SentryId ToSentryId(this CocoaSdk.SentryId sentryId) => new(Guid.Parse(sentryId.SentryIdString));
- public static CocoaSdk.SentryId ToCocoaSentryId(this SentryId sentryId) => new(sentryId.ToString());
-
public static SpanId ToSpanId(this CocoaSdk.SentrySpanId spanId) => new(spanId.SentrySpanIdString);
- public static CocoaSdk.SentrySpanId ToCocoaSpanId(this SpanId spanId) => new(spanId.ToString());
+ // The SentryObjCSDK.internal hybrid API uses its own id types (SentryObjCId / SentryObjCSpanId)
+ // rather than the Sentry.framework SentryId / SentrySpanId used elsewhere.
+ public static CocoaSdk.SentryObjCId ToCocoaObjCId(this SentryId sentryId) => new(sentryId.ToString());
+
+ public static CocoaSdk.SentryObjCSpanId ToCocoaObjCSpanId(this SpanId spanId) => new(spanId.ToString());
}
diff --git a/src/Sentry/Platforms/Cocoa/RuntimeAdapter.cs b/src/Sentry/Platforms/Cocoa/RuntimeAdapter.cs
index 21e9200201..c7534a0f63 100644
--- a/src/Sentry/Platforms/Cocoa/RuntimeAdapter.cs
+++ b/src/Sentry/Platforms/Cocoa/RuntimeAdapter.cs
@@ -25,7 +25,7 @@ private RuntimeAdapter()
public bool IsMono { get; } = Type.GetType("Mono.Runtime") != null;
- public void IgnoreNextSignal(int signal) => SentryCocoaHybridSdk.IgnoreNextSignal(signal);
+ public void IgnoreNextSignal(int signal) => SentryCocoaHybridSdk.Internal.IgnoreNextSignal(signal);
[SecurityCritical]
private void OnMarshalManagedException(object sender, MarshalManagedExceptionEventArgs e) => MarshalManagedException?.Invoke(this, e);
diff --git a/src/Sentry/Platforms/Cocoa/Sentry.Cocoa.props b/src/Sentry/Platforms/Cocoa/Sentry.Cocoa.props
index 3c98f1fc4e..7f02ed04c3 100644
--- a/src/Sentry/Platforms/Cocoa/Sentry.Cocoa.props
+++ b/src/Sentry/Platforms/Cocoa/Sentry.Cocoa.props
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Sentry/Platforms/Cocoa/SentrySdk.cs b/src/Sentry/Platforms/Cocoa/SentrySdk.cs
index 9fd3f62ef5..2b0df2a7e3 100644
--- a/src/Sentry/Platforms/Cocoa/SentrySdk.cs
+++ b/src/Sentry/Platforms/Cocoa/SentrySdk.cs
@@ -166,7 +166,7 @@ private static void InitSentryCocoaSdk(SentryOptions options)
}
// Set hybrid SDK name
- SentryCocoaHybridSdk.SetSdkName("sentry.cocoa.dotnet");
+ SentryCocoaHybridSdk.Internal.Sdk.Name = "sentry.cocoa.dotnet";
// Now initialize the Cocoa SDK
SentryCocoaSdk.StartWithOptions(nativeOptions);