From 1eef006e7b66fc1def25a2d077778afda3eff917 Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Mon, 7 Sep 2026 17:09:04 +0200 Subject: [PATCH 1/2] feat: fix Xcode 27 build issues --- .../ios/Sources/DdFlagsImplementation.swift | 7 ++- .../ios/Sources/DdLogsImplementation.swift | 16 +++---- .../ios/Sources/DdRumImplementation.swift | 46 +++++++++---------- .../ios/Sources/DdSdkImplementation.swift | 41 ++++++++--------- .../ios/Sources/DdTraceImplementation.swift | 4 +- .../core/ios/Sources/RCTPromiseTypes.swift | 18 ++++++++ .../ios/Sources/DdSessionReplay.mm | 2 + .../DdSessionReplayImplementation.swift | 8 ++-- .../ios/Sources/RCTPromiseTypes.swift | 18 ++++++++ 9 files changed, 98 insertions(+), 62 deletions(-) create mode 100644 packages/core/ios/Sources/RCTPromiseTypes.swift create mode 100644 packages/react-native-session-replay/ios/Sources/RCTPromiseTypes.swift diff --git a/packages/core/ios/Sources/DdFlagsImplementation.swift b/packages/core/ios/Sources/DdFlagsImplementation.swift index 26b13727f..34020f410 100644 --- a/packages/core/ios/Sources/DdFlagsImplementation.swift +++ b/packages/core/ios/Sources/DdFlagsImplementation.swift @@ -26,7 +26,7 @@ public class DdFlagsImplementation: NSObject { } @objc - public func enable(_ configuration: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { + public func enable(_ configuration: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) { // Client providers become stale upon subsequent enable calls (which can happen e.g. in case of a React Native hot reload). clientProviders.removeAll() @@ -53,9 +53,8 @@ public class DdFlagsImplementation: NSObject { return client } - // Using @escaping RCTPromiseResolveBlock type will result in an issue when compiling the Swift header file. @objc - public func setEvaluationContext(_ clientName: String, targetingKey: String, attributes: NSDictionary, resolve: @escaping ((Any?) -> Void), reject: @escaping ((String?, String?, NSError?) -> Void)) { + public func setEvaluationContext(_ clientName: String, targetingKey: String, attributes: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) { let client = getClient(name: clientName) guard let clientInternal = client as? FlagsClientInternal else { reject("CLIENT_NOT_INITIALIZED", "Flags client '\(clientName)' is not properly initialized. Make sure the Datadog SDK has been initialized and Flags.enable() has been called.", nil) @@ -102,7 +101,7 @@ public class DdFlagsImplementation: NSObject { } @objc - public func trackEvaluation(_ clientName: String, key: String, rawFlag: NSDictionary, targetingKey: String, attributes: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { + public func trackEvaluation(_ clientName: String, key: String, rawFlag: NSDictionary, targetingKey: String, attributes: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) { guard let client = getClient(name: clientName) as? FlagsClientInternal else { reject("CLIENT_NOT_INITIALIZED", "Flags client '\(clientName)' is not properly initialized. Make sure the Datadog SDK has been initialized and Flags.enable() has been called.", nil) return diff --git a/packages/core/ios/Sources/DdLogsImplementation.swift b/packages/core/ios/Sources/DdLogsImplementation.swift index a4a8ba04a..584ddd284 100644 --- a/packages/core/ios/Sources/DdLogsImplementation.swift +++ b/packages/core/ios/Sources/DdLogsImplementation.swift @@ -36,56 +36,56 @@ public class DdLogsImplementation: NSObject { } @objc - public func debug(message: String, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func debug(message: String, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger.debug(message, error: nil, attributes: attributes) resolve(nil) } @objc - public func info(message: String, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func info(message: String, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger.info(message, error: nil, attributes: attributes) resolve(nil) } @objc - public func warn(message: String, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func warn(message: String, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger.warn(message, error: nil, attributes: attributes) resolve(nil) } @objc - public func error(message: String, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func error(message: String, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger.error(message, error: nil, attributes: attributes) resolve(nil) } @objc - public func debugWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func debugWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger._internal.log(level: .debug, message: message, errorKind: errorKind, errorMessage: errorMessage, stackTrace: stacktrace, attributes: attributes) resolve(nil) } @objc - public func infoWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func infoWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger._internal.log(level: .info, message: message, errorKind: errorKind, errorMessage: errorMessage, stackTrace: stacktrace, attributes: attributes) resolve(nil) } @objc - public func warnWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func warnWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger._internal.log(level: .warn, message: message, errorKind: errorKind, errorMessage: errorMessage, stackTrace: stacktrace, attributes: attributes) resolve(nil) } @objc - public func errorWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func errorWithError(message: String, errorKind: String?, errorMessage: String?, stacktrace: String?, context: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let attributes = castAttributesToSwift(context).mergeWithGlobalAttributes() logger._internal.log(level: .error, message: message, errorKind: errorKind, errorMessage: errorMessage, stackTrace: stacktrace, attributes: attributes) resolve(nil) diff --git a/packages/core/ios/Sources/DdRumImplementation.swift b/packages/core/ios/Sources/DdRumImplementation.swift index fec42b407..97372f6d5 100644 --- a/packages/core/ios/Sources/DdRumImplementation.swift +++ b/packages/core/ios/Sources/DdRumImplementation.swift @@ -131,31 +131,31 @@ public class DdRumImplementation: NSObject { } @objc - public func startView(key: String, name: String, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func startView(key: String, name: String, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.startView(key: key, name: name, attributes: attributes(from: context, with: timestampMs)) resolve(nil) } @objc - public func stopView(key: String, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func stopView(key: String, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.stopView(key: key, attributes: attributes(from: context, with: timestampMs)) resolve(nil) } @objc - public func startAction(type: String, name: String, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func startAction(type: String, name: String, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.startAction(type: RUMActionType(from: type), name: name, attributes: attributes(from: context, with: timestampMs)) resolve(nil) } @objc - public func stopAction(type: String, name: String, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func stopAction(type: String, name: String, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.stopAction(type: RUMActionType(from: type), name: name, attributes: attributes(from: context, with: timestampMs)) resolve(nil) } @objc - public func addAction(type: String, name: String, touch: NSDictionary?, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addAction(type: String, name: String, touch: NSDictionary?, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { if let touch, let reactTag = touch["reactTag"] as? NSNumber, @@ -180,13 +180,13 @@ public class DdRumImplementation: NSObject { } @objc - public func startResource(key: String, method: String, url: String, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func startResource(key: String, method: String, url: String, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.startResource(resourceKey: key, httpMethod: RUMMethod(from: method), urlString: url, attributes: attributes(from: context, with: timestampMs)) resolve(nil) } @objc - public func stopResource(key: String, statusCode: Int64, kind: String, size: Double, context: NSDictionary, timestampMs: Double, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func stopResource(key: String, statusCode: Int64, kind: String, size: Double, context: NSDictionary, timestampMs: Double, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let mutableContext = NSMutableDictionary(dictionary: context) if let resourceTimings = mutableContext.object(forKey: Self.resourceTimingsKey) as? [String: Any] { mutableContext.removeObject(forKey: Self.resourceTimingsKey) @@ -205,7 +205,7 @@ public class DdRumImplementation: NSObject { } @objc - public func addError(message: String, source: String, stacktrace: String, context: NSDictionary, timestampMs: Double, fingerprint: String, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addError(message: String, source: String, stacktrace: String, context: NSDictionary, timestampMs: Double, fingerprint: String, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { func addErrorWithContext(errorContext: NSDictionary) -> Void { nativeRUM.addError(message: message, type: nil, stack: stacktrace, source: RUMErrorSource(from: source), attributes: attributes(from: errorContext, with: timestampMs), file: nil, line: nil) @@ -223,13 +223,13 @@ public class DdRumImplementation: NSObject { } @objc - public func addTiming(name: String, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addTiming(name: String, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.addTiming(name: name) resolve(nil) } @objc - public func addViewAttribute(key: AttributeKey, value: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addViewAttribute(key: AttributeKey, value: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { if let attributeValue = value.object(forKey: "value") { let castedAttribute = castValueToSwift(attributeValue) nativeRUM.addViewAttribute(forKey: key, value: castedAttribute) @@ -238,38 +238,38 @@ public class DdRumImplementation: NSObject { } @objc - public func removeViewAttribute(key: AttributeKey, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func removeViewAttribute(key: AttributeKey, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.removeViewAttribute(forKey: key) resolve(nil) } @objc - public func addViewAttributes(attributes: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addViewAttributes(attributes: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let castedAttributes = castAttributesToSwift(attributes) nativeRUM.addViewAttributes(castedAttributes) resolve(nil) } @objc - public func removeViewAttributes(keys: [AttributeKey], resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func removeViewAttributes(keys: [AttributeKey], resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.removeViewAttributes(forKeys: keys) resolve(nil) } @objc - public func addViewLoadingTime(overwrite: Bool, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addViewLoadingTime(overwrite: Bool, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.addViewLoadingTime(overwrite: overwrite) resolve(nil) } @objc - public func stopSession(resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func stopSession(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.stopSession() resolve(nil) } @objc - public func addFeatureFlagEvaluation(name: String, value: NSDictionary, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func addFeatureFlagEvaluation(name: String, value: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let valueAsEncodable = castAttributesToSwift(value) if let value = valueAsEncodable["value"] { nativeRUM.addFeatureFlagEvaluation(name: name, value: value) @@ -278,7 +278,7 @@ public class DdRumImplementation: NSObject { } @objc - public func getCurrentSessionId(_ resolve: @escaping (Any?) -> Void, reject: RCTPromiseRejectBlock) -> Void { + public func getCurrentSessionId(_ resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { nativeRUM.currentSessionID { sessionId in resolve(sessionId) } @@ -289,8 +289,8 @@ public class DdRumImplementation: NSObject { name: String, operationKey: String?, attributes: NSDictionary, - resolve: @escaping (Any?) -> Void, - reject: RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ){ let castedAttributes = castAttributesToSwift(attributes) nativeRUM.startFeatureOperation(name: name, operationKey: operationKey, attributes: castedAttributes) @@ -302,8 +302,8 @@ public class DdRumImplementation: NSObject { name: String, operationKey: String?, attributes: NSDictionary, - resolve: @escaping (Any?) -> Void, - reject: RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ){ let castedAttributes = castAttributesToSwift(attributes) nativeRUM.succeedFeatureOperation(name: name, operationKey: operationKey, attributes: castedAttributes) @@ -316,8 +316,8 @@ public class DdRumImplementation: NSObject { operationKey: String?, reason: String, attributes: NSDictionary, - resolve: @escaping (Any?) -> Void, - reject: RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ){ let castedAttributes = castAttributesToSwift(attributes) nativeRUM.failFeatureOperation(name: name, operationKey: operationKey, diff --git a/packages/core/ios/Sources/DdSdkImplementation.swift b/packages/core/ios/Sources/DdSdkImplementation.swift index 7a838055a..d12564c4d 100644 --- a/packages/core/ios/Sources/DdSdkImplementation.swift +++ b/packages/core/ios/Sources/DdSdkImplementation.swift @@ -62,11 +62,10 @@ public class DdSdkImplementation: NSObject { super.init() } - // Using @escaping RCTPromiseResolveBlock type will result in an issue when compiling the Swift header file. @objc public func initialize( - configuration: NSDictionary, resolve: @escaping ((Any?) -> Void), - reject: RCTPromiseRejectBlock + configuration: NSDictionary, resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ) { let sdkConfiguration = configuration.asDdSdkConfiguration() let nativeInitialization = DdSdkNativeInitialization() @@ -94,8 +93,8 @@ public class DdSdkImplementation: NSObject { @objc public func addAttribute( - key: AttributeKey, value: NSDictionary, resolve: RCTPromiseResolveBlock, - reject: RCTPromiseRejectBlock + key: AttributeKey, value: NSDictionary, resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ) { if let attributeValue = value.object(forKey: "value") { let castedValue = castValueToSwift(attributeValue) @@ -108,7 +107,7 @@ public class DdSdkImplementation: NSObject { @objc public func removeAttribute( - key: AttributeKey, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + key: AttributeKey, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { RUMMonitorProvider()?.removeAttribute(forKey: key) GlobalState.removeAttribute(key: key) @@ -118,7 +117,7 @@ public class DdSdkImplementation: NSObject { @objc public func addAttributes( - attributes: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + attributes: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { let castedAttributes = castAttributesToSwift(attributes) for (key, value) in castedAttributes { @@ -131,7 +130,7 @@ public class DdSdkImplementation: NSObject { @objc public func removeAttributes( - keys: [AttributeKey], resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + keys: [AttributeKey], resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { RUMMonitorProvider()?.removeAttributes(forKeys: keys) for (key) in keys { @@ -143,7 +142,7 @@ public class DdSdkImplementation: NSObject { @objc public func setUserInfo( - userInfo: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + userInfo: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { let castedUserInfo = castAttributesToSwift(userInfo) let id = castedUserInfo["id"] as? String @@ -166,7 +165,7 @@ public class DdSdkImplementation: NSObject { @objc public func addUserExtraInfo( - extraInfo: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + extraInfo: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { let castedExtraInfo = castAttributesToSwift(extraInfo) @@ -175,14 +174,14 @@ public class DdSdkImplementation: NSObject { } @objc - public func clearUserInfo(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { + public func clearUserInfo(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) { Datadog.clearUserInfo() resolve(nil) } @objc public func setAccountInfo( - accountInfo: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + accountInfo: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { let castedAccountInfo = castAttributesToSwift(accountInfo) let id = castedAccountInfo["id"] as? String @@ -204,7 +203,7 @@ public class DdSdkImplementation: NSObject { @objc public func addAccountExtraInfo( - extraInfo: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + extraInfo: NSDictionary, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { let castedExtraInfo = castAttributesToSwift(extraInfo) @@ -213,14 +212,14 @@ public class DdSdkImplementation: NSObject { } @objc - public func clearAccountInfo(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { + public func clearAccountInfo(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) { Datadog.clearAccountInfo() resolve(nil) } @objc public func setTrackingConsent( - trackingConsent: NSString, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + trackingConsent: NSString, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { Datadog.set(trackingConsent: (trackingConsent as NSString?).asTrackingConsent()) resolve(nil) @@ -229,7 +228,7 @@ public class DdSdkImplementation: NSObject { @objc public func sendTelemetryLog( message: NSString, attributes: NSDictionary, config: NSDictionary, - resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { let castedAttributes = castAttributesToSwift(attributes) let castedConfig = castAttributesToSwift(config) @@ -241,7 +240,7 @@ public class DdSdkImplementation: NSObject { @objc public func telemetryDebug( - message: NSString, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + message: NSString, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { DdTelemetry.telemetryDebug( id: "datadog_react_native:\(message)", message: message as String) @@ -250,8 +249,8 @@ public class DdSdkImplementation: NSObject { @objc public func telemetryError( - message: NSString, stack: NSString, kind: NSString, resolve: RCTPromiseResolveBlock, - reject: RCTPromiseRejectBlock + message: NSString, stack: NSString, kind: NSString, resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ) { DdTelemetry.telemetryError( id: "datadog_react_native:\(String(describing: kind)):\(message)", @@ -262,7 +261,7 @@ public class DdSdkImplementation: NSObject { #if os(iOS) @objc public func consumeWebviewEvent( - message: NSString, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + message: NSString, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { do { try DatadogSDKWrapper.shared.sendWebviewMessage(body: message) @@ -280,7 +279,7 @@ public class DdSdkImplementation: NSObject { #endif @objc - public func clearAllData(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { + public func clearAllData(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) { Datadog.clearAllData() resolve(nil) } diff --git a/packages/core/ios/Sources/DdTraceImplementation.swift b/packages/core/ios/Sources/DdTraceImplementation.swift index f8073e215..8d9e5da89 100644 --- a/packages/core/ios/Sources/DdTraceImplementation.swift +++ b/packages/core/ios/Sources/DdTraceImplementation.swift @@ -31,7 +31,7 @@ public class DdTraceImplementation: NSObject { @objc public func startSpan( operation: String, context: NSDictionary, timestampMs: Double, - resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { objc_sync_enter(self) defer { objc_sync_exit(self) } @@ -57,7 +57,7 @@ public class DdTraceImplementation: NSObject { @objc public func finishSpan( spanId: NSString, context: NSDictionary, timestampMs: Double, - resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject ) { objc_sync_enter(self) defer { objc_sync_exit(self) } diff --git a/packages/core/ios/Sources/RCTPromiseTypes.swift b/packages/core/ios/Sources/RCTPromiseTypes.swift new file mode 100644 index 000000000..6f1749332 --- /dev/null +++ b/packages/core/ios/Sources/RCTPromiseTypes.swift @@ -0,0 +1,18 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +import Foundation + +/// Local equivalents of `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` from `React/RCTBridgeModule.h`. +/// +/// Using these plain Swift closure types instead of React's typealiases keeps the generated +/// Objective-C interface header (`-Swift.h`) from referencing `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` +/// by name: Swift emits the underlying block signature directly instead, so the header no longer +/// depends on `RCTBridgeModule.h` being importable wherever it is consumed. The block signatures are +/// structurally identical to React's, so `.mm` callers can pass `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` +/// values through unchanged. +public typealias RCTPromiseResolve = (Any?) -> Void +public typealias RCTPromiseReject = (String, String, NSError?) -> Void diff --git a/packages/react-native-session-replay/ios/Sources/DdSessionReplay.mm b/packages/react-native-session-replay/ios/Sources/DdSessionReplay.mm index 616865da8..4cd9855ef 100644 --- a/packages/react-native-session-replay/ios/Sources/DdSessionReplay.mm +++ b/packages/react-native-session-replay/ios/Sources/DdSessionReplay.mm @@ -3,12 +3,14 @@ * This product includes software developed at Datadog (https://www.datadoghq.com/). * Copyright 2016-Present Datadog, Inc. */ + // Import this first to prevent require cycles #if __has_include("DatadogSDKReactNativeSessionReplay-Swift.h") #import #else #import #endif + #import "DdSessionReplay.h" diff --git a/packages/react-native-session-replay/ios/Sources/DdSessionReplayImplementation.swift b/packages/react-native-session-replay/ios/Sources/DdSessionReplayImplementation.swift index ef1f70330..ee182b4cd 100644 --- a/packages/react-native-session-replay/ios/Sources/DdSessionReplayImplementation.swift +++ b/packages/react-native-session-replay/ios/Sources/DdSessionReplayImplementation.swift @@ -76,8 +76,8 @@ public class DdSessionReplayImplementation: NSObject { startRecordingImmediately: Bool, enableHeatmaps: Bool, enableCompositionTreeRecording: Bool, - resolve:RCTPromiseResolveBlock, - reject:RCTPromiseRejectBlock + resolve: @escaping RCTPromiseResolve, + reject: @escaping RCTPromiseReject ) -> Void { var customEndpointURL: URL? = nil if (customEndpoint != "") { @@ -109,13 +109,13 @@ public class DdSessionReplayImplementation: NSObject { } @objc - public func startRecording(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { + public func startRecording(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { sessionReplay.startRecording(in: CoreRegistry.default) resolve(nil) } @objc - public func stopRecording(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { + public func stopRecording(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { sessionReplay.stopRecording(in: CoreRegistry.default) resolve(nil) } diff --git a/packages/react-native-session-replay/ios/Sources/RCTPromiseTypes.swift b/packages/react-native-session-replay/ios/Sources/RCTPromiseTypes.swift new file mode 100644 index 000000000..6f1749332 --- /dev/null +++ b/packages/react-native-session-replay/ios/Sources/RCTPromiseTypes.swift @@ -0,0 +1,18 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +import Foundation + +/// Local equivalents of `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` from `React/RCTBridgeModule.h`. +/// +/// Using these plain Swift closure types instead of React's typealiases keeps the generated +/// Objective-C interface header (`-Swift.h`) from referencing `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` +/// by name: Swift emits the underlying block signature directly instead, so the header no longer +/// depends on `RCTBridgeModule.h` being importable wherever it is consumed. The block signatures are +/// structurally identical to React's, so `.mm` callers can pass `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` +/// values through unchanged. +public typealias RCTPromiseResolve = (Any?) -> Void +public typealias RCTPromiseReject = (String, String, NSError?) -> Void From 1e6fa2cd9edcb2dc154276b5d634466182fd5bc6 Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Tue, 8 Sep 2026 11:00:30 +0200 Subject: [PATCH 2/2] chore: internal-testing-tools internal react promise-block types --- .../DdInternalTestingImplementation.swift | 9 ++++----- .../ios/Sources/RCTPromiseTypes.swift | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 packages/internal-testing-tools/ios/Sources/RCTPromiseTypes.swift diff --git a/packages/internal-testing-tools/ios/Sources/DdInternalTestingImplementation.swift b/packages/internal-testing-tools/ios/Sources/DdInternalTestingImplementation.swift index 41a213efd..b5be3979b 100644 --- a/packages/internal-testing-tools/ios/Sources/DdInternalTestingImplementation.swift +++ b/packages/internal-testing-tools/ios/Sources/DdInternalTestingImplementation.swift @@ -5,7 +5,6 @@ */ import Foundation -import React import DatadogCore import DatadogSDKReactNative import DatadogInternal @@ -13,7 +12,7 @@ import DatadogInternal @objc public class DdInternalTestingImplementation: NSObject { @objc - public func clearData(resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func clearData(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { let coreProxy = CoreRegistry.default as! DatadogCoreProxy coreProxy.waitAndDeleteEvents(ofFeature: "rum") coreProxy.waitAndDeleteEvents(ofFeature: "logging") @@ -24,7 +23,7 @@ public class DdInternalTestingImplementation: NSObject { } @objc - public func getAllEvents(feature: String, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func getAllEvents(feature: String, resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { do { let coreProxy = CoreRegistry.default as! DatadogCoreProxy let events = coreProxy.waitAndReturnEventsData(ofFeature: feature) @@ -32,13 +31,13 @@ public class DdInternalTestingImplementation: NSObject { resolve(String(data: data, encoding: String.Encoding.utf8) ?? "") } catch { consolePrint("\(error)", .error) - reject(nil, "Cannot serialize events, check XCode console for more information", nil) + reject("JSON_SERIALIZATION_ERROR", "Cannot serialize events, check XCode console for more information", nil) } return } @objc - public func enable(resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void { + public func enable(resolve: @escaping RCTPromiseResolve, reject: @escaping RCTPromiseReject) -> Void { DatadogSDKWrapper.shared.addOnSdkInitializedListener(listener: {core in let proxiedCore = DatadogCoreProxy(core: core) CoreRegistry.unregisterDefault() diff --git a/packages/internal-testing-tools/ios/Sources/RCTPromiseTypes.swift b/packages/internal-testing-tools/ios/Sources/RCTPromiseTypes.swift new file mode 100644 index 000000000..6f1749332 --- /dev/null +++ b/packages/internal-testing-tools/ios/Sources/RCTPromiseTypes.swift @@ -0,0 +1,18 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +import Foundation + +/// Local equivalents of `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` from `React/RCTBridgeModule.h`. +/// +/// Using these plain Swift closure types instead of React's typealiases keeps the generated +/// Objective-C interface header (`-Swift.h`) from referencing `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` +/// by name: Swift emits the underlying block signature directly instead, so the header no longer +/// depends on `RCTBridgeModule.h` being importable wherever it is consumed. The block signatures are +/// structurally identical to React's, so `.mm` callers can pass `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` +/// values through unchanged. +public typealias RCTPromiseResolve = (Any?) -> Void +public typealias RCTPromiseReject = (String, String, NSError?) -> Void