Skip to content

feat(apple): wire Sentry Metrics API via new SentryObjC framework#1352

Open
philprime wants to merge 47 commits into
mainfrom
philprime/apple-metrics
Open

feat(apple): wire Sentry Metrics API via new SentryObjC framework#1352
philprime wants to merge 47 commits into
mainfrom
philprime/apple-metrics

Conversation

@philprime

Copy link
Copy Markdown
Member

Swap the Apple (macOS + iOS) platform integration from sentry-cocoa's Sentry.framework + sentry.dylib pair to the new standalone SentryObjC.framework + SentryObjC.dylib, which bundles the full SDK and exposes a pure Objective-C wrapper that doesn't require Clang modules. This unlocks the Sentry Metrics ObjC API ([SentrySDK metrics] returning an id<SentryMetricsApi> with countWithKey: / distributionWithKey: / gaugeWithKey:), so FAppleSentrySubsystem::AddCount / AddDistribution / AddGauge — previously no-op stubs — now forward to the native SDK. A new VariantToAttributeContentNative + VariantMapToAttributeContentNative pair converts FSentryVariant into SentryAttributeContent instances for metric attributes.

Why SentryObjC instead of the existing Sentry framework?

The Metrics API on sentry-cocoa is Swift-first. Calling it directly from the plugin required either enabling Clang modules in Unreal's build (invasive and brittle across engine versions) or using the new pure-ObjC wrapper framework the sentry-cocoa team has been building for exactly this scenario. The SentryObjC wrapper now ships every public type we need without pulling in Swift modules.

Framework-surface differences this PR adapts to

  • AppleSentryInclude.h imports the single <SentryObjC/SentryObjC.h> umbrella instead of three separate <Sentry/...> headers.
  • SENTRY_UIKIT_AVAILABLE renamed to SENTRY_OBJC_UIKIT_AVAILABLE — the new framework publishes a parallel macro under the SENTRY_OBJC_ prefix to avoid clashing with the core Sentry module's existing macro when both are in the same TU.
  • @class SentryFeedback; / @class SentryLog; forward declarations dropped from AppleSentryFeedback.h / AppleSentryLog.h in favor of importing AppleSentryInclude.h. Upstream aliases those class names via @compatibility_alias, which refuses to apply to a name that is already forward-declared in the same translation unit.
  • Sentry.Build.cs + SentryModule.cpp reference the new SentryObjC framework/dylib filenames.

Draft — not mergeable yet

scripts/download-cocoa.sh is temporarily patched to pull the SentryObjC xcframework from a getsentry/sentry-cocoa CI artifact via gh run download. This was needed because the upstream branch (philprime/objc-wrapper-sdk-6342) hasn't shipped in a sentry-cocoa release yet. The script needs to be restored to release-based download before merge, pointed at the first sentry-cocoa release that contains SentryObjC-Dynamic.xcframework.zip.

Validation

  • Mac: RunUAT BuildCookRun -platform=Mac compiles + links + xcodebuild passes cleanly against the new framework.
  • iOS: RunUAT BuildCookRun -platform=IOS compiles + links cleanly against the new framework. The xcodebuild PostBuildSync step fails only on a local "requires a development team" signing-config issue, which is unrelated to this change.

philprime and others added 2 commits April 22, 2026 18:45
Switch the Apple (macOS + iOS) platform integration from sentry-cocoa's
`Sentry.framework` + `sentry.dylib` pair to the new standalone
`SentryObjC.framework` + `SentryObjC.dylib`, which bundles the full SDK
and exposes a pure Objective-C wrapper that doesn't require Clang modules.

This unlocks the Sentry Metrics ObjC API (`[SentrySDK metrics]` returning
an `id<SentryMetricsApi>` with `countWithKey:`, `distributionWithKey:`,
`gaugeWithKey:`). Implements `AddCount`, `AddDistribution`, `AddGauge`
that were previously no-op stubs, and adds
`VariantToAttributeContentNative` / `VariantMapToAttributeContentNative`
converters to map `FSentryVariant` to `SentryAttributeContent` for
metric attributes.

Additional fixes required by the new framework's surface:

  - Update `AppleSentryInclude.h` to import the single `<SentryObjC/SentryObjC.h>`
    umbrella instead of three separate `<Sentry/...>` headers.
  - Rename `SENTRY_UIKIT_AVAILABLE` to `SENTRY_OBJC_UIKIT_AVAILABLE`; the
    new framework publishes a parallel macro under the `SENTRY_OBJC_`
    prefix to avoid clashing with the core `Sentry` module's version.
  - Drop `@class SentryFeedback;` / `@class SentryLog;` forward
    declarations from `AppleSentryFeedback.h` and `AppleSentryLog.h` in
    favor of importing `AppleSentryInclude.h`. Upstream aliases those
    class names via `@compatibility_alias`, which refuses to apply to a
    name already forward-declared in the same TU.
  - `Sentry.Build.cs` + `SentryModule.cpp` now reference the
    `SentryObjC` framework/dylib filenames.

`scripts/download-cocoa.sh` is temporarily patched to pull the SentryObjC
xcframework from a getsentry/sentry-cocoa CI artifact via `gh run download`
instead of the release URL, since no release containing this framework has
shipped yet. This must be reverted before merge — a follow-up will restore
the release-based download once a suitable sentry-cocoa version is published.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@philprime philprime self-assigned this Apr 22, 2026
philprime and others added 2 commits April 24, 2026 15:38
…CAttributeContent

sentry-cocoa's SentryObjC target renamed its public ObjC wrapper classes to
the `SentryObjC`-prefixed form (SentryAttributeContent.h → SentryObjCAttributeContent.h,
plus the matching class rename inside) to disambiguate from other Swift
SDK-owned types of the same name. Update our Metrics API converter and
AddCount/AddDistribution/AddGauge call sites to reference the new class name.

Also bump `scripts/download-cocoa.sh` to pull the latest CI artifact that
ships both the rename and the earlier `@compatibility_alias` shims for
Swift-mangled classes (run 24890645262, sha ea03ca4e). Verified end-to-end:
Mac `BuildCookRun` passes xcodebuild; iOS compile + link are clean (only
remaining failure is the local signing-config issue, unrelated to this
change).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	plugin-dev/Source/Sentry/Private/Apple/Convenience/AppleSentryInclude.h
#	plugin-dev/Source/Sentry/Private/SentryModule.cpp
#	plugin-dev/Source/Sentry/Sentry.Build.cs
#	scripts/download-cocoa.sh
@github-actions

github-actions Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 2720605

philprime and others added 2 commits May 27, 2026 17:26
All Objective-C types from sentry-cocoa now use a uniform `SentryObjC`
prefix. Update all Apple platform wrapper files to match the redesigned
SentryObjC SDK headers.

Key changes:
- Rename all ObjC types from `SentryXxx` to `SentryObjCXxx`
- Change `id<SentrySpan>` to `SentryObjCSpan*` (protocol → class)
- Update enum values to `SentryObjC*` prefix
- Use `captureFeedbackWithMessage:` instead of removed `captureFeedback:`
- Switch metrics unit from `NSString*` to `SentryObjCUnit*`
- Update `SentryObjCMetricValue` and `SentryObjCAttributeContent` factory
  method names to match new SDK API
- Remove `beforeSendLog`/`beforeSendMetric` callbacks (no longer on options)
- Fix xcframework slice paths for arm64e in download script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tustanivsky tustanivsky marked this pull request as ready for review June 4, 2026 07:27
@tustanivsky tustanivsky self-requested a review as a code owner June 4, 2026 07:27
Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp
Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp
Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp
Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp
Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp Outdated
Comment on lines +584 to 594
return FSentryVariant(static_cast<int32>([(NSNumber*)content.value integerValue]));
}
else if ([type isEqualToString:@"double"])
{
return FSentryVariant(static_cast<float>([(NSNumber*)content.value doubleValue]));
}

return FSentryVariant();
}

#endif // !USE_SENTRY_NATIVE

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The function SentryAttributeContentToVariant lacks support for array types, causing silent data loss when reading back array attributes from metrics that were previously set.
Severity: MEDIUM

Suggested Fix

Update the SentryAttributeContentToVariant function to handle array types. Add logic to recognize the type strings for arrays (e.g., stringArray, integerArray) from the native SentryObjCAttributeContent and convert them into the corresponding FSentryVariant array types. This will ensure round-trip conversion for metric attributes works correctly.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
plugin-dev/Source/Sentry/Private/Apple/Infrastructure/AppleSentryConverters.cpp#L562-L594

Potential issue: An asymmetric conversion exists between `FSentryVariant` and the native
`SentryObjCAttributeContent`. The function `VariantToAttributeContentNative` can convert
array variants to native objects, but the reverse function,
`SentryAttributeContentToVariant`, does not handle array types. If a user sets an
array-typed attribute on a metric and then reads it back using `GetAttribute` or
`TryGetAttribute`, the conversion back to `FSentryVariant` fails. This results in an
empty variant being returned, causing silent data loss of the array attribute.

Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp Outdated
@limbonaut

Copy link
Copy Markdown
Collaborator

This PR is probably affected by this issue same as Godot's:

dlopen omits link-time validation, so the build tools can't surface such issues.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2720605. Configure here.

return FSentryVariant(static_cast<float>([(NSNumber*)content.value doubleValue]));
}

return FSentryVariant();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array metric attributes not read back

Medium Severity

SentryAttributeContentToVariant only maps string, boolean, integer, and double types. VariantToAttributeContentNative can emit typed arrays via stringArray, integerArray, and similar helpers, so FAppleSentryMetric attribute reads return empty variants for those keys after round-trip or in beforeSendMetric handlers.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2720605. Configure here.

Comment thread plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants