From 45bd94f5bdf33f41e901559c1be68e1501ba8e0d Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 17 Jul 2026 13:56:51 +0200 Subject: [PATCH 1/2] bumped to obj-c --- .github/workflows/sdk.yml | 2 +- build/native-sdks.targets | 2 +- modules/sentry-cocoa | 2 +- package-dev/Plugins/iOS/SentryNativeBridge.m | 59 ++++++-------- .../Plugins/macOS/SentryNativeBridge.m | 79 +++++++++---------- scripts/build-cocoa-sdk.ps1 | 29 +++---- scripts/download-native-sdks.ps1 | 2 +- .../BuildPostProcess.cs | 2 +- src/Sentry.Unity.Editor.iOS/NativeMain.cs | 6 +- src/Sentry.Unity.Editor.iOS/NativeOptions.cs | 13 ++- .../SentryXcodeProject.cs | 2 +- .../SentryXcodeProjectTests.cs | 2 +- .../TestFiles/2019_4/main_expected.txt | 6 +- 13 files changed, 94 insertions(+), 112 deletions(-) diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index 4af4e2162..93da1db3c 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -106,7 +106,7 @@ jobs: with: name: ${{ env.TARGET }}-sdk path: | - package-dev/Plugins/iOS/Sentry.xcframework~ + package-dev/Plugins/iOS/SentryObjC.xcframework~ package-dev/Plugins/macOS/Sentry~ # Lower retention period - we only need this to retry CI. retention-days: 14 diff --git a/build/native-sdks.targets b/build/native-sdks.targets index 237587ae3..1a9e80d70 100644 --- a/build/native-sdks.targets +++ b/build/native-sdks.targets @@ -4,7 +4,7 @@ $(RepoRoot)modules/sentry-cocoa/ - $(SentryArtifactsDestination)iOS/Sentry.xcframework~/ + $(SentryArtifactsDestination)iOS/SentryObjC.xcframework~/ $(SentryArtifactsDestination)macOS/Sentry~/ $(SentryArtifactsDestination)macOS/SentryNative~/ diff --git a/modules/sentry-cocoa b/modules/sentry-cocoa index 53eb9bd5d..67310f115 160000 --- a/modules/sentry-cocoa +++ b/modules/sentry-cocoa @@ -1 +1 @@ -Subproject commit 53eb9bd5da18e208cfd80e86863d3f4c7ba21b1d +Subproject commit 67310f115f3fc1e5e1f2e262f9009c64bb387e3f diff --git a/package-dev/Plugins/iOS/SentryNativeBridge.m b/package-dev/Plugins/iOS/SentryNativeBridge.m index f9d643af3..4c56e9c73 100644 --- a/package-dev/Plugins/iOS/SentryNativeBridge.m +++ b/package-dev/Plugins/iOS/SentryNativeBridge.m @@ -1,8 +1,5 @@ -#import #import -#import -#import -#import +#import NS_ASSUME_NONNULL_BEGIN @@ -43,7 +40,7 @@ // On iOS, the SDK is linked statically so we don't need to dlopen() it. int SentryNativeBridgeLoadLibrary() { return 1; } -int SentryNativeBridgeIsEnabled() { return [SentrySDK isEnabled] ? 1 : 0; } +int SentryNativeBridgeIsEnabled() { return [SentryObjCSDK isEnabled] ? 1 : 0; } const void *SentryNativeBridgeOptionsNew() { @@ -80,7 +77,7 @@ void SentryNativeBridgeOptionsAddFailedRequestStatusCodeRange(const void *option ranges = [[NSMutableArray alloc] init]; dictOptions[@"failedRequestStatusCodes"] = ranges; } - [ranges addObject:[[SentryHttpStatusCodeRange alloc] initWithMin:min max:max]]; + [ranges addObject:[[SentryObjCHttpStatusCodeRange alloc] initWithMin:min max:max]]; } int SentryNativeBridgeStartWithOptions(const void *options) @@ -88,24 +85,24 @@ int SentryNativeBridgeStartWithOptions(const void *options) NSMutableDictionary *dictOptions = (__bridge_transfer NSMutableDictionary *)options; NSError *error = nil; - SentryOptions *sentryOptions = [SentryOptionsInternal initWithDict:dictOptions didFailWithError:&error]; + SentryObjCOptions *sentryOptions = [[SentryObjCSDK internal] optionsFromDictionary:dictOptions error:&error]; if (error != nil) { return 0; } - [SentrySDK startWithOptions:sentryOptions]; + [SentryObjCSDK startWithOptions:sentryOptions]; return 1; } void SentryNativeBridgeSetSdkName() { - [PrivateSentrySDKOnly performSelector:@selector(setSdkName:) withObject:@"sentry.cocoa.unity"]; + [SentryObjCSDK internal].sdk.name = @"sentry.cocoa.unity"; } -int SentryNativeBridgeCrashedLastRun() { return [SentrySDK crashedLastRun] ? 1 : 0; } +int SentryNativeBridgeCrashedLastRun() { return [SentryObjCSDK crashedLastRun] ? 1 : 0; } -void SentryNativeBridgeClose() { [SentrySDK close]; } +void SentryNativeBridgeClose() { [SentryObjCSDK close]; } void SentryNativeBridgeAddBreadcrumb(const char *timestamp, const char *message, const char *type, const char *category, int level, const char **dataKeys, const char **dataValues, int dataCount) @@ -119,8 +116,8 @@ void SentryNativeBridgeAddBreadcrumb(const char *timestamp, const char *message, NSString *typeString = _NSStringOrNil(type); NSString *categoryString = _NSStringOrNil(category) ?: @"default"; // Category cannot be nil - [SentrySDK configureScope:^(SentryScope *scope) { - SentryBreadcrumb *breadcrumb = [[SentryBreadcrumb alloc] + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { + SentryObjCBreadcrumb *breadcrumb = [[SentryObjCBreadcrumb alloc] initWithLevel:level category:categoryString]; @@ -164,7 +161,7 @@ void SentryNativeBridgeSetExtra(const char *key, const char *value) NSString *keyString = [NSString stringWithUTF8String:key]; NSString *valueString = _NSStringOrNil(value); - [SentrySDK configureScope:^(SentryScope *scope) { + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { [scope setExtraValue:valueString forKey:keyString]; }]; } @@ -178,7 +175,7 @@ void SentryNativeBridgeSetTag(const char *key, const char *value) NSString *keyString = [NSString stringWithUTF8String:key]; NSString *valueString = _NSStringOrNil(value); - [SentrySDK configureScope:^(SentryScope *scope) { + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { [scope setTagValue:valueString forKey:keyString]; }]; } @@ -191,7 +188,7 @@ void SentryNativeBridgeUnsetTag(const char *key) NSString *keyString = [NSString stringWithUTF8String:key]; - [SentrySDK configureScope:^(SentryScope *scope) { + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { [scope removeTagForKey:keyString]; }]; } @@ -204,8 +201,8 @@ void SentryNativeBridgeSetUser( NSString *ipAddressString = _NSStringOrNil(ipAddress); NSString *usernameString = _NSStringOrNil(username); - [SentrySDK configureScope:^(SentryScope *scope) { - SentryUser *user = [[SentryUser alloc] init]; + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { + SentryObjCUser *user = [[SentryObjCUser alloc] init]; user.email = emailString; user.userId = userIdString; @@ -218,14 +215,14 @@ void SentryNativeBridgeSetUser( void SentryNativeBridgeUnsetUser() { - [SentrySDK configureScope:^(SentryScope *scope) { [scope setUser:nil]; }]; + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { [scope setUser:nil]; }]; } char *SentryNativeBridgeGetInstallationId() { // Create a null terminated C string on the heap as expected by marshalling. // See Tips for iOS in https://docs.unity3d.com/Manual/PluginsForIOS.html - const char *nsStringUtf8 = [[PrivateSentrySDKOnly installationID] UTF8String]; + const char *nsStringUtf8 = [[SentryObjCSDK internal].sdk.installationID UTF8String]; size_t len = strlen(nsStringUtf8) + 1; char *cString = (char *)malloc(len); memcpy(cString, nsStringUtf8, len); @@ -241,17 +238,11 @@ void SentryNativeBridgeSetTrace(const char *traceId, const char *spanId) NSString *traceIdStr = [NSString stringWithUTF8String:traceId]; NSString *spanIdStr = [NSString stringWithUTF8String:spanId]; - // This is a workaround to deal with SentryId living inside the Swift header - Class sentryIdClass = NSClassFromString(@"SentryId"); - Class sentrySpanIdClass = NSClassFromString(@"SentrySpanId"); + SentryObjCId *sentryTraceId = [[SentryObjCId alloc] initWithUUIDString:traceIdStr]; + SentryObjCSpanId *sentrySpanId = [[SentryObjCSpanId alloc] initWithValue:spanIdStr]; - if (sentryIdClass && sentrySpanIdClass) { - id sentryTraceId = [[sentryIdClass alloc] initWithUUIDString:traceIdStr]; - id sentrySpanId = [[sentrySpanIdClass alloc] initWithValue:spanIdStr]; - - if (sentryTraceId && sentrySpanId) { - [PrivateSentrySDKOnly setTrace:sentryTraceId spanId:sentrySpanId]; - } + if (sentryTraceId && sentrySpanId) { + [[SentryObjCSDK internal] setTrace:sentryTraceId spanId:sentrySpanId]; } } @@ -292,7 +283,7 @@ void SentryNativeBridgeWriteScope( // clang-format off ) // clang-format on { // Note: we're using a NSMutableDictionary because it will skip fields with nil values. - [SentrySDK configureScope:^(SentryScope *scope) { + [SentryObjCSDK configureScope:^(SentryObjCScope *scope) { NSMutableDictionary *gpu = [[NSMutableDictionary alloc] init]; gpu[@"id"] = _NSNumberOrNil(GpuId); gpu[@"name"] = _NSStringOrNil(GpuName); @@ -309,7 +300,7 @@ void SentryNativeBridgeWriteScope( // clang-format off gpu[@"vendor_id"] = _NSStringOrNil(GpuVendorId); gpu[@"multi_threaded_rendering"] = _NSBoolOrNil(GpuMultiThreadedRendering); gpu[@"graphics_shader_level"] = _NSStringOrNil(GpuGraphicsShaderLevel); - [scope performSelector:@selector(setContextValue:forKey:) withObject:gpu withObject:@"gpu"]; + [scope setContextValue:gpu forKey:@"gpu"]; NSMutableDictionary *unity = [[NSMutableDictionary alloc] init]; unity[@"editor_version"] = _NSStringOrNil(EditorVersion); @@ -317,9 +308,7 @@ void SentryNativeBridgeWriteScope( // clang-format off unity[@"target_frame_rate"] = _NSStringOrNil(UnityTargetFrameRate); unity[@"copy_texture_support"] = _NSStringOrNil(UnityCopyTextureSupport); unity[@"rendering_threading_mode"] = _NSStringOrNil(UnityRenderingThreadingMode); - [scope performSelector:@selector(setContextValue:forKey:) - withObject:unity - withObject:@"unity"]; + [scope setContextValue:unity forKey:@"unity"]; }]; } diff --git a/package-dev/Plugins/macOS/SentryNativeBridge.m b/package-dev/Plugins/macOS/SentryNativeBridge.m index 52270547f..61a800e8a 100644 --- a/package-dev/Plugins/macOS/SentryNativeBridge.m +++ b/package-dev/Plugins/macOS/SentryNativeBridge.m @@ -37,16 +37,12 @@ static int loadStatus = -1; // unitialized -static Class SentrySDK; -static Class SentryScope; -static Class SentryBreadcrumb; -static Class SentryUser; -static Class SentryOptions; -static Class SentryOptionsInternal; -static Class SentryId; -static Class SentrySpanId; -static Class PrivateSentrySDKOnly; -static Class SentryHttpStatusCodeRange; +static Class SentryObjCSDK; +static Class SentryObjCBreadcrumb; +static Class SentryObjCUser; +static Class SentryObjCId; +static Class SentryObjCSpanId; +static Class SentryObjCHttpStatusCodeRange; #define LOAD_CLASS_OR_BREAK(name) \ name = (__bridge Class)dlsym(dylib, "OBJC_CLASS_$_" #name); \ @@ -55,12 +51,11 @@ break; \ } -#define LOAD_SWIFT_CLASS_OR_BREAK(name, mangled_name) \ - name = (__bridge Class)dlsym(dylib, "OBJC_CLASS_$_" #mangled_name); \ - if (!name) { \ - NSLog(@"Sentry (bridge): Couldn't load class '" #name "' from the dynamic library"); \ - break; \ - } +// The SentryObjC wrapper classes are plain Objective-C (@objc(SentryObjC...)), so unlike the +// previous `SentrySDK` Swift class they load by their unmangled OBJC_CLASS_$_ symbol. +// [SentryObjCSDK internal] is the hybrid-SDK entry point used for options parsing, SDK metadata, +// and trace propagation. +static id SentryInternalApi(void) { return [SentryObjCSDK performSelector:@selector(internal)]; } // Returns (bool): 0 on failure, 1 on success // WARNING: you may only call other Sentry* functions AFTER calling this AND only if it returned "1" @@ -80,16 +75,12 @@ int SentryNativeBridgeLoadLibrary() } } - LOAD_SWIFT_CLASS_OR_BREAK(SentrySDK, _TtC6Sentry9SentrySDK) - LOAD_CLASS_OR_BREAK(SentryScope) - LOAD_CLASS_OR_BREAK(SentryBreadcrumb) - LOAD_CLASS_OR_BREAK(SentryUser) - LOAD_CLASS_OR_BREAK(SentryOptions) - LOAD_CLASS_OR_BREAK(SentryOptionsInternal) - LOAD_CLASS_OR_BREAK(SentryId) - LOAD_CLASS_OR_BREAK(SentrySpanId) - LOAD_CLASS_OR_BREAK(PrivateSentrySDKOnly) - LOAD_CLASS_OR_BREAK(SentryHttpStatusCodeRange) + LOAD_CLASS_OR_BREAK(SentryObjCSDK) + LOAD_CLASS_OR_BREAK(SentryObjCBreadcrumb) + LOAD_CLASS_OR_BREAK(SentryObjCUser) + LOAD_CLASS_OR_BREAK(SentryObjCId) + LOAD_CLASS_OR_BREAK(SentryObjCSpanId) + LOAD_CLASS_OR_BREAK(SentryObjCHttpStatusCodeRange) // everything above passed - mark as successfully loaded loadStatus = 1; @@ -98,7 +89,7 @@ int SentryNativeBridgeLoadLibrary() return loadStatus; } -int SentryNativeBridgeIsEnabled() { return [SentrySDK isEnabled] ? 1 : 0; } +int SentryNativeBridgeIsEnabled() { return [SentryObjCSDK isEnabled] ? 1 : 0; } const void *SentryNativeBridgeOptionsNew() { @@ -135,7 +126,7 @@ void SentryNativeBridgeOptionsAddFailedRequestStatusCodeRange(const void *option ranges = [[NSMutableArray alloc] init]; dictOptions[@"failedRequestStatusCodes"] = ranges; } - id instance = [SentryHttpStatusCodeRange alloc]; + id instance = [SentryObjCHttpStatusCodeRange alloc]; // initWithMin:max: takes NSInteger args - use objc_msgSend directly id range = ((id (*)(id, SEL, NSInteger, NSInteger))objc_msgSend)( instance, @selector(initWithMin:max:), (NSInteger)min, (NSInteger)max); @@ -149,8 +140,8 @@ int SentryNativeBridgeStartWithOptions(const void *options) NSMutableDictionary *dictOptions = (__bridge_transfer NSMutableDictionary *)options; NSError *error = nil; - id sentryOptions = [SentryOptionsInternal - performSelector:@selector(initWithDict:didFailWithError:) + id sentryOptions = [SentryInternalApi() + performSelector:@selector(optionsFromDictionary:error:) withObject:dictOptions withObject:&error]; if (error != nil) @@ -158,7 +149,7 @@ int SentryNativeBridgeStartWithOptions(const void *options) return 0; } - [SentrySDK performSelector:@selector(startWithOptions:) withObject:sentryOptions]; + [SentryObjCSDK performSelector:@selector(startWithOptions:) withObject:sentryOptions]; return 1; } @@ -168,7 +159,7 @@ void SentryConfigureScope(void (^callback)(id)) // Even though this shouldn't happen, better not take the chance of letting an unhandled // exception while setting error info - it would just crash the app immediately. @try { - [SentrySDK performSelector:@selector(configureScope:) withObject:callback]; + [SentryObjCSDK performSelector:@selector(configureScope:) withObject:callback]; } @catch (NSException *exception) { NSLog(@"Sentry (bridge): failed to configure scope: %@", exception.reason); } @@ -186,13 +177,14 @@ void SentryConfigureScope(void (^callback)(id)) void SentryNativeBridgeSetSdkName() { - [PrivateSentrySDKOnly performSelector:@selector(setSdkName:) withObject:@"sentry.cocoa.unity"]; + id sdkApi = [SentryInternalApi() performSelector:@selector(sdk)]; + [sdkApi performSelector:@selector(setName:) withObject:@"sentry.cocoa.unity"]; } int SentryNativeBridgeCrashedLastRun() { @try { - return [SentrySDK performSelector:@selector(crashedLastRun)] ? 1 : 0; + return [SentryObjCSDK performSelector:@selector(crashedLastRun)] ? 1 : 0; } @catch (NSException *exception) { NSLog(@"Sentry (bridge): failed to get crashedLastRun: %@", exception.reason); } @@ -202,7 +194,7 @@ int SentryNativeBridgeCrashedLastRun() void SentryNativeBridgeClose() { @try { - [SentrySDK performSelector:@selector(close)]; + [SentryObjCSDK performSelector:@selector(close)]; } @catch (NSException *exception) { NSLog(@"Sentry (bridge): failed to close: %@", exception.reason); } @@ -221,7 +213,7 @@ void SentryNativeBridgeAddBreadcrumb(const char *timestamp, const char *message, NSString *categoryString = _NSStringOrNil(category) ?: @"default"; // Category cannot be nil SentryConfigureScope(^(id scope) { - id breadcrumb = [[SentryBreadcrumb alloc] init]; + id breadcrumb = [[SentryObjCBreadcrumb alloc] init]; if (timestampString != nil && timestampString.length > 0) { NSDate *date = [sentry_cachedISO8601Formatter() dateFromString:timestampString]; @@ -314,7 +306,7 @@ void SentryNativeBridgeSetUser( NSString *usernameString = _NSStringOrNil(username); SentryConfigureScope(^(id scope) { - id user = [[SentryUser alloc] init]; + id user = [[SentryObjCUser alloc] init]; [user setValue:emailString forKey:@"email"]; [user setValue:userIdString forKey:@"userId"]; @@ -335,8 +327,9 @@ void SentryNativeBridgeUnsetUser() { // Create a null terminated C string on the heap as expected by marshalling. // See Tips for iOS in https://docs.unity3d.com/Manual/PluginsForIOS.html + id sdkApi = [SentryInternalApi() performSelector:@selector(sdk)]; const char *nsStringUtf8 = - [[PrivateSentrySDKOnly performSelector:@selector(installationID)] UTF8String]; + [[sdkApi performSelector:@selector(installationID)] UTF8String]; size_t len = strlen(nsStringUtf8) + 1; char *cString = (char *)malloc(len); memcpy(cString, nsStringUtf8, len); @@ -349,17 +342,17 @@ void SentryNativeBridgeSetTrace(const char *traceId, const char *spanId) return; } - id sentryTraceId = [[SentryId alloc] + id sentryTraceId = [[SentryObjCId alloc] performSelector:@selector(initWithUUIDString:) withObject:[NSString stringWithUTF8String:traceId]]; - id sentrySpanId = [[SentrySpanId alloc] + id sentrySpanId = [[SentryObjCSpanId alloc] performSelector:@selector(initWithValue:) withObject:[NSString stringWithUTF8String:spanId]]; - [PrivateSentrySDKOnly - performSelector:@selector(setTrace:spanId:) - withObject:sentryTraceId + [SentryInternalApi() + performSelector:@selector(setTrace:spanId:) + withObject:sentryTraceId withObject:sentrySpanId]; } diff --git a/scripts/build-cocoa-sdk.ps1 b/scripts/build-cocoa-sdk.ps1 index c2e81dbe1..55b85d9d6 100644 --- a/scripts/build-cocoa-sdk.ps1 +++ b/scripts/build-cocoa-sdk.ps1 @@ -24,8 +24,8 @@ if (-not (Test-Path (Join-Path $CocoaRoot "Sentry.xcodeproj"))) { # All build artifacts go under XCFrameworkBuildPath/ which is already in sentry-cocoa's .gitignore. $buildPath = Join-Path $CocoaRoot "XCFrameworkBuildPath" -$iOSXcframeworkPath = Join-Path $buildPath "Sentry-Dynamic-iOS.xcframework" -$macOSXcframeworkPath = Join-Path $buildPath "Sentry-Dynamic-macOS.xcframework" +$iOSXcframeworkPath = Join-Path $buildPath "SentryObjC-Dynamic-iOS.xcframework" +$macOSXcframeworkPath = Join-Path $buildPath "SentryObjC-Dynamic-macOS.xcframework" if ($Clean -and (Test-Path $buildPath)) { Write-Host "Clean build requested — removing $buildPath" -ForegroundColor Yellow @@ -40,13 +40,14 @@ try { if (-not (Test-Path $iOSXcframeworkPath)) { Write-Host "Building iOS xcframework..." -ForegroundColor Yellow - # Exclude arm64e from the binary. Since Xcode 26, apps without arm64e in the main binary - # can't include frameworks with arm64e slices (App Store rejection). The sentry-cocoa SDK - # ships separate "-WithARM64e" variants for apps that need it; Unity games don't. - & ./scripts/build-xcframework-variant.sh --scheme "Sentry" --suffix "-Dynamic" --mach-o-type "mh_dylib" --sdks "iOSOnly" --excluded-archs "arm64e" - & ./scripts/validate-xcframework-format.sh --xcframework "Sentry-Dynamic.xcframework" - # build-xcframework-variant.sh outputs to the working directory — move into our build cache - Move-Item -Path "Sentry-Dynamic.xcframework" -Destination $iOSXcframeworkPath -Force + # SentryObjC is the public ObjC wrapper SDK. The dynamic xcframework embeds the full SDK + # (SentryObjC + SentryObjCCompat + SentryObjCInternal) into a single self-contained framework, + # so Unity links/dlopens only one binary. The dynamic slices are arm64-only (no arm64e), so no + # architecture stripping is needed — unlike the main `Sentry` scheme's Xcode-project build. + & ./scripts/build-xcframework-sentryobjc.sh --sdks "iphoneos,iphonesimulator" --variant dynamic + & ./scripts/validate-xcframework-format.sh --xcframework "SentryObjC-Dynamic.xcframework" + # build-xcframework-sentryobjc.sh outputs to the working directory — move into our build cache + Move-Item -Path "SentryObjC-Dynamic.xcframework" -Destination $iOSXcframeworkPath -Force # Clean up intermediate archives, keep the final xcframework $archivePath = Join-Path $buildPath "archive" if (Test-Path $archivePath) { @@ -76,9 +77,9 @@ try { if (-not (Test-Path $macOSXcframeworkPath)) { Write-Host "Building macOS xcframework..." -ForegroundColor Yellow - & ./scripts/build-xcframework-variant.sh --scheme "Sentry" --suffix "-Dynamic" --mach-o-type "mh_dylib" --sdks "macOSOnly" - & ./scripts/validate-xcframework-format.sh --xcframework "Sentry-Dynamic.xcframework" - Move-Item -Path "Sentry-Dynamic.xcframework" -Destination $macOSXcframeworkPath -Force + & ./scripts/build-xcframework-sentryobjc.sh --sdks "macosx" --variant dynamic + & ./scripts/validate-xcframework-format.sh --xcframework "SentryObjC-Dynamic.xcframework" + Move-Item -Path "SentryObjC-Dynamic.xcframework" -Destination $macOSXcframeworkPath -Force # Clean up all remaining build intermediates foreach ($dir in @("archive", "DerivedData")) { $dirPath = Join-Path $buildPath $dir @@ -95,8 +96,8 @@ try { Write-Error "No macOS slice found in xcframework at: $macOSXcframeworkPath" exit 1 } - $macOSFrameworkPath = Join-Path $macOSSlice.FullName "Sentry.framework/Versions/A/Sentry" - $macOSdSYMPath = Join-Path $macOSSlice.FullName "dSYMs/Sentry.framework.dSYM/Contents/Resources/DWARF/Sentry" + $macOSFrameworkPath = Join-Path $macOSSlice.FullName "SentryObjC.framework/Versions/A/SentryObjC" + $macOSdSYMPath = Join-Path $macOSSlice.FullName "dSYMs/SentryObjC.framework.dSYM/Contents/Resources/DWARF/SentryObjC" $macOSDestDir = Split-Path $macOSDestination -Parent if (-not (Test-Path $macOSDestDir)) { diff --git a/scripts/download-native-sdks.ps1 b/scripts/download-native-sdks.ps1 index 7000e8b20..3794510c1 100644 --- a/scripts/download-native-sdks.ps1 +++ b/scripts/download-native-sdks.ps1 @@ -43,7 +43,7 @@ $SDKs = @( Name = "Cocoa" Destination = $ArtifactsDestination CheckFiles = @( - "iOS/Sentry.xcframework~/Info.plist", + "iOS/SentryObjC.xcframework~/Info.plist", "macOS/Sentry~/Sentry.dylib" ) }, diff --git a/src/Sentry.Unity.Editor.iOS/BuildPostProcess.cs b/src/Sentry.Unity.Editor.iOS/BuildPostProcess.cs index ee4702ec2..1285ed51d 100644 --- a/src/Sentry.Unity.Editor.iOS/BuildPostProcess.cs +++ b/src/Sentry.Unity.Editor.iOS/BuildPostProcess.cs @@ -117,7 +117,7 @@ internal static void SetupSentry(SentryUnityOptions options, IDiagnosticLogger l try { - // The Sentry.xcframework ends in '~' to hide it from Unity. This prevents Unity from exporting it with the Xcode build. + // The SentryObjC.xcframework ends in '~' to hide it from Unity. This prevents Unity from exporting it with the Xcode build. // Ideally, we would let Unity copy this over but: // - Detection of `.xcframework` as datatype and non-folder happened in Unity 2021 // - Without a `.meta` file we cannot opt-in embedding the framework diff --git a/src/Sentry.Unity.Editor.iOS/NativeMain.cs b/src/Sentry.Unity.Editor.iOS/NativeMain.cs index fa4c7d531..30b408cd3 100644 --- a/src/Sentry.Unity.Editor.iOS/NativeMain.cs +++ b/src/Sentry.Unity.Editor.iOS/NativeMain.cs @@ -9,14 +9,14 @@ internal static class NativeMain { public const string Include = @"#import #import -#import +#import #include ""SentryOptions.m"" "; private const string Init = @" - SentryOptions* options = getSentryOptions(); + SentryObjCOptions* options = getSentryOptions(); if(options != nil) { - [SentrySDK startWithOptions:options]; + [SentryObjCSDK startWithOptions:options]; } "; diff --git a/src/Sentry.Unity.Editor.iOS/NativeOptions.cs b/src/Sentry.Unity.Editor.iOS/NativeOptions.cs index 6de8450e4..8522eeb12 100644 --- a/src/Sentry.Unity.Editor.iOS/NativeOptions.cs +++ b/src/Sentry.Unity.Editor.iOS/NativeOptions.cs @@ -11,17 +11,16 @@ internal static string Generate(SentryUnityOptions options) { var failedRequestStatusCodesArray = GetFailedRequestStatusCodesArray(options.FailedRequestStatusCodes); var nativeOptions = $@"#import -#import -#import +#import // IMPORTANT: Changes to this file will be lost! // This file is generated during the Xcode project creation. // To learn more please take a look at our docs at: https://docs.sentry.io/platforms/unity/native-support/ -static SentryOptions* getSentryOptions() +static SentryObjCOptions* getSentryOptions() {{ - [PrivateSentrySDKOnly setSdkName:@""sentry.cocoa.unity""]; + [SentryObjCSDK internal].sdk.name = @""sentry.cocoa.unity""; NSDictionary* optionsDictionary = @{{ @""dsn"" : @""{options.Dsn}"", @@ -43,14 +42,14 @@ internal static string Generate(SentryUnityOptions options) }}; NSError *error = nil; - SentryOptions *sentryOptions = [SentryOptionsInternal initWithDict:optionsDictionary didFailWithError:&error]; + SentryObjCOptions *sentryOptions = [[SentryObjCSDK internal] optionsFromDictionary:optionsDictionary error:&error]; if (error != nil) {{ NSLog(@""%@"",[error localizedDescription]); return nil; }} - {(options.FilterBadGatewayExceptions ? @"sentryOptions.beforeSend = ^SentryEvent * _Nullable(SentryEvent * _Nonnull event) { + {(options.FilterBadGatewayExceptions ? @"sentryOptions.beforeSend = ^SentryObjCEvent * _Nullable(SentryObjCEvent * _Nonnull event) { if ([event.request.url containsString:@""operate-sdk-telemetry.unity3d.com""]) return nil; return event; };" : "")} @@ -81,7 +80,7 @@ private static string GetFailedRequestStatusCodesArray(IList #import -#import +#import #include "SentryOptions.m" #include @@ -26,10 +26,10 @@ int main(int argc, char* argv[]) { @autoreleasepool { - SentryOptions* options = getSentryOptions(); + SentryObjCOptions* options = getSentryOptions(); if(options != nil) { - [SentrySDK startWithOptions:options]; + [SentryObjCSDK startWithOptions:options]; } id ufw = UnityFrameworkLoad(); From cf19d71f9d9e4f9a646cb6df134d8f96de5bc605 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 17 Jul 2026 14:00:40 +0200 Subject: [PATCH 2/2] updated changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d09cdfdc1..5da799008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,15 @@ ## Unreleased +### Fixes + +- Migrated the native support for iOS and macOS to use the Obj-C flavour of `sentry-cocoa` ([#2767](https://github.com/getsentry/sentry-unity/pull/2767)) + ### Dependencies +- Bump Cocoa SDK from v9.21.0 to v9.22.0 ([#2763](https://github.com/getsentry/sentry-unity/pull/2763)) + - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#9220) + - [diff](https://github.com/getsentry/sentry-cocoa/compare/9.21.0...9.22.0) - Bump .NET SDK from v6.5.0-33-g0140be0a to v6.6.0 ([#2761](https://github.com/getsentry/sentry-unity/pull/2761)) - [changelog](https://github.com/getsentry/sentry-dotnet/blob/main/CHANGELOG.md#660) - [diff](https://github.com/getsentry/sentry-dotnet/compare/6.5.0-33-g0140be0a...6.6.0)