Skip to content

[iOS] Session Replay fails to build with Xcode 27: Unknown type name 'RCTPromiseResolveBlock' in generated -Swift.h header #1382

Description

@benupstart

Describe the bug

The @datadog/mobile-react-native-session-replay fails to compile under Xcode 27 beta (Swift 6.4):

In file included from node_modules/@datadog/mobile-react-native-session-replay/ios/Sources/DdSessionReplay.mm:8:
DerivedSources/DatadogSDKReactNativeSessionReplay-Swift.h:788:415: error: unknown type name 'RCTPromiseResolveBlock'
DerivedSources/DatadogSDKReactNativeSessionReplay-Swift.h:788:478: error: unknown type name 'RCTPromiseRejectBlock'
DerivedSources/DatadogSDKReactNativeSessionReplay-Swift.h:789:51:  error: unknown type name 'RCTPromiseResolveBlock'
DerivedSources/DatadogSDKReactNativeSessionReplay-Swift.h:789:114: error: unknown type name 'RCTPromiseRejectBlock'
DerivedSources/DatadogSDKReactNativeSessionReplay-Swift.h:790:50:  error: unknown type name 'RCTPromiseResolveBlock'
DerivedSources/DatadogSDKReactNativeSessionReplay-Swift.h:790:113: error: unknown type name 'RCTPromiseRejectBlock'
6 errors generated.

Why it happens

The pod's Swift code exposes three methods to Objective-C (enable, startRecording, stopRecording), and their signatures use React Native's promise-callback types, RCTPromiseResolveBlock and RCTPromiseRejectBlock. When Xcode builds the pod, it auto-generates an Objective-C header (DatadogSDKReactNativeSessionReplay-Swift.h) from those Swift methods — and that generated header mentions the two React typedefs without ever importing the React header that defines them (React/RCTBridgeModule.h).

It has technically always been broken, but Xcode 26 and earlier papered over it: the compiler would implicitly resolve the missing types through its module system. Xcode 27's Swift 6.4 toolchain stopped doing that, so the typedefs are now genuinely undefined where they're used, and compilation fails.

Our fix

We patch the package locally (Yarn patch). The core change: in the Swift file, replace the two React typealiases with their exact structural equivalents, (Any?) -> Void for resolve and (String?, String?, Error?) -> Void for reject. These are the same underlying types, so nothing changes at runtime; but the generated header no longer references any React names, so it compiles regardless of import order. Two defensive React imports were also added on the Objective-C side.

Reproduction steps

  1. RN app with @datadog/mobile-react-native-session-replay (any version incl. 3.6.0), New Architecture enabled, static libraries (no use_frameworks!)
  2. Build with Xcode 27
  3. Compilation of the session-replay pod fails with the error above

SDK logs

No response

Expected behavior

Suggested fix, we expect the build to complete and not fail:

Replace the RCT typealiases in the @objc method signatures with their structural equivalents, so the generated header emits raw block types with no React dependency:

// Before
public func startRecording(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {

// After
public func startRecording(resolve: (Any?) -> Void, reject: (String?, String?, Error?) -> Void) -> Void {

Affected SDK versions

3.6.0

Latest working SDK version

NA (not working on any version)

Did you confirm if the latest SDK version fixes the bug?

Yes

Integration Methods

NPM

React Native Version

0.85.2

Package.json Contents

No response

iOS Setup

No response

Android Setup

No response

Device Information

No response

Other relevant information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions