@react-native-firebase/perf 26.4.0 → 27.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/RNFBPerf.podspec +6 -1
  3. package/android/build.gradle +3 -0
  4. package/android/src/main/java/io/invertase/firebase/perf/RNFBPerfHandleRegistry.kt +71 -0
  5. package/android/src/test/java/io/invertase/firebase/perf/RNFBPerfHandleRegistryTest.java +30 -0
  6. package/dist/module/version.js +1 -1
  7. package/dist/typescript/lib/index.d.ts +1 -1
  8. package/dist/typescript/lib/version.d.ts +1 -1
  9. package/ios/RNFBPerf/RNFBPerfHandleRegistry.m +28 -9
  10. package/ios/RNFBPerf/RNFBPerfHandleRegistryStorage.swift +58 -0
  11. package/ios/RNFBPerf/RNFBPerfHelper.h +71 -0
  12. package/ios/RNFBPerf/RNFBPerfHelper.m +219 -0
  13. package/ios/RNFBPerf/RNFBPerfHttpMethodMapper.swift +86 -0
  14. package/ios/RNFBPerf/RNFBPerfHttpMetricStopApplier.swift +87 -0
  15. package/ios/RNFBPerf/RNFBPerfModule.mm +35 -172
  16. package/ios/RNFBPerf/RNFBPerfTraceStopApplier.swift +68 -0
  17. package/ios/RNFBPerf.xcodeproj/project.pbxproj +32 -0
  18. package/ios/RNFBPerfUnitTests/HostStubs/Firebase/FIRPerformanceHostStub.m +170 -0
  19. package/ios/RNFBPerfUnitTests/HostStubs/Firebase/Firebase.h +75 -0
  20. package/ios/RNFBPerfUnitTests/HostStubs/RNFBApp/RNFBSharedUtils.h +12 -0
  21. package/ios/RNFBPerfUnitTests/HostStubs/RNFBApp/RNFBSharedUtilsHostStub.m +18 -0
  22. package/ios/RNFBPerfUnitTests/HostStubs/React/RCTBridgeModule.h +10 -0
  23. package/ios/RNFBPerfUnitTests/RNFBPerfHandleRegistryTests.m +46 -0
  24. package/ios/RNFBPerfUnitTests/RNFBPerfHelperHostStubTests.m +200 -0
  25. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMethodMapperFacadeTests.m +52 -0
  26. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMethodMapperTests.swift +92 -0
  27. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMetricStopApplierFacadeTests.m +105 -0
  28. package/ios/RNFBPerfUnitTests/RNFBPerfHttpMetricStopApplierTests.swift +201 -0
  29. package/ios/RNFBPerfUnitTests/RNFBPerfTraceStopApplierFacadeTests.m +75 -0
  30. package/ios/RNFBPerfUnitTests/RNFBPerfTraceStopApplierTests.swift +142 -0
  31. package/ios/RNFBPerfUnitTests/RNFBPerfUnitTests.xcodeproj/project.pbxproj +70 -0
  32. package/lib/version.ts +1 -1
  33. package/package.json +4 -4
  34. package/android/src/main/java/io/invertase/firebase/perf/RNFBPerfHandleRegistry.java +0 -72
package/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [27.1.0](https://github.com/invertase/react-native-firebase/compare/v27.0.0...v27.1.0) (2026-10-23)
7
+
8
+ **Note:** Version bump only for package @react-native-firebase/perf
9
+
10
+ ## [27.0.0](https://github.com/invertase/react-native-firebase/compare/v26.4.0...v27.0.0) (2026-10-19)
11
+
12
+ ### ⚠ BREAKING CHANGES
13
+
14
+ - **app, sdk:** bump Firebase Android 35, Apple 13, and JS 13
15
+
16
+ ### Features
17
+
18
+ - **app, sdk:** bump Firebase Android 35, Apple 13, and JS 13 ([0ca03d1](https://github.com/invertase/react-native-firebase/commit/0ca03d11b0c271fb37cfbee8a0c3074a21969f0b))
19
+
20
+ ### Bug Fixes
21
+
22
+ - **perf, ios:** avoid id cast shadowed by TurboModule id param ([9556118](https://github.com/invertase/react-native-firebase/commit/955611850796e2589c0286ab4700a4eb6ec5d2a3))
23
+ - **perf, ios:** typedef Swift protocol refs around TurboModule id shadowing ([db9cc60](https://github.com/invertase/react-native-firebase/commit/db9cc60e6eb2eb4331702393e2649f102b7cce70))
24
+ - **perf, ios:** use id casts for Swift protocols in ObjC++ ([1d5c7ca](https://github.com/invertase/react-native-firebase/commit/1d5c7ca28d674d7c3bdd19d085911abccda2b20e))
25
+
6
26
  ## [26.4.0](https://github.com/invertase/react-native-firebase/compare/v26.3.3...v26.4.0) (2026-09-05)
7
27
 
8
28
  ### Bug Fixes
package/RNFBPerf.podspec CHANGED
@@ -29,16 +29,21 @@ Pod::Spec.new do |s|
29
29
  s.ios.deployment_target = firebase_ios_target
30
30
  s.macos.deployment_target = firebase_macos_target
31
31
  s.tvos.deployment_target = firebase_tvos_target
32
+ s.swift_version = '5.10'
32
33
  s.source_files = 'ios/**/*.{h,m,mm,cpp,swift}'
33
34
  s.private_header_files = "ios/**/*.h"
34
- s.exclude_files = 'ios/generated/RCTThirdPartyComponentsProvider.*', 'ios/generated/RCTAppDependencyProvider.*', 'ios/generated/RCTModuleProviders.*', 'ios/generated/RCTModulesConformingToProtocolsProvider.*', 'ios/generated/RCTUnstableModulesRequiringMainQueueSetupProvider.*', 'ios/*UnitTests/**'
35
+ # CocoaPods FileList uses FNM_PATHNAME: `ios/*UnitTests/**` does not match nested
36
+ # paths like `ios/RNFBPerfUnitTests/HostStubs/**` (those would compile into the pod).
37
+ s.exclude_files = 'ios/generated/RCTThirdPartyComponentsProvider.*', 'ios/generated/RCTAppDependencyProvider.*', 'ios/generated/RCTModuleProviders.*', 'ios/generated/RCTModulesConformingToProtocolsProvider.*', 'ios/generated/RCTUnstableModulesRequiringMainQueueSetupProvider.*', 'ios/*UnitTests/**/*'
35
38
 
36
39
  # Must be set before install_modules_dependencies so RN can append use_frameworks
37
40
  # HEADER_SEARCH_PATHS (React-debug etc.). Assigning after overwrites those paths
38
41
  # and breaks from-source builds: react/timing/primitives.h → react/debug/flags.h.
39
42
  # CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES is required so the
40
43
  # framework module validates when consumers build with use_frameworks!.
44
+ # DEFINES_MODULE is required for the generated RNFBPerf-Swift.h interface.
41
45
  s.pod_target_xcconfig = {
46
+ "DEFINES_MODULE" => "YES",
42
47
  "CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES" => "YES",
43
48
  }
44
49
 
@@ -15,6 +15,7 @@ buildscript {
15
15
 
16
16
  dependencies {
17
17
  classpath("com.android.tools.build:gradle:8.4.0")
18
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.findProperty('kotlinVersion') ?: '2.4.0'}")
18
19
  }
19
20
  }
20
21
  }
@@ -23,6 +24,8 @@ plugins {
23
24
  id "io.invertase.gradle.build" version "1.5"
24
25
  }
25
26
 
27
+ apply plugin: "org.jetbrains.kotlin.android"
28
+
26
29
  def appProject
27
30
  if (findProject(':@react-native-firebase_app')) {
28
31
  appProject = project(':@react-native-firebase_app')
@@ -0,0 +1,71 @@
1
+ package io.invertase.firebase.perf
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import io.invertase.firebase.common.RNFBHandleCollisionException
21
+ import io.invertase.firebase.common.RNFBHandleMap
22
+ import java.util.function.Predicate
23
+
24
+ /**
25
+ * Perf id → metric handle map (traces, screen traces, HTTP metrics). Module start paths use
26
+ * [putReplacing] (last wins, stop displaced outside lock). Unique [put] / [putOrDiscard] remain for
27
+ * tests. Callers [get] then [take] then stop outside the HandleMap lock. Tear-down discards via
28
+ * [takeAll] without stopping (matches prior SparseArray clear).
29
+ */
30
+ internal class RNFBPerfHandleRegistry<V> {
31
+ private val map = RNFBHandleMap<Int, V>()
32
+
33
+ @Throws(RNFBHandleCollisionException::class)
34
+ fun put(
35
+ id: Int,
36
+ handle: V,
37
+ ) {
38
+ map.put(id, handle)
39
+ }
40
+
41
+ /**
42
+ * Unique put. On collision, drop the incoming handle without stopping and leave the existing
43
+ * mapping.
44
+ *
45
+ * @return true if stored
46
+ */
47
+ fun putOrDiscard(
48
+ id: Int,
49
+ handle: V,
50
+ ): Boolean = map.putIfAbsent(id, handle)
51
+
52
+ /**
53
+ * Atomically replaces the mapping for [id] (last wins). Returns the displaced handle, or `null`
54
+ * if the id was free. Stop the displaced handle after this method returns.
55
+ */
56
+ fun putReplacing(
57
+ id: Int,
58
+ handle: V,
59
+ ): V? = map.putReplacing(id, handle)
60
+
61
+ fun get(id: Int): V? = map.get(id)
62
+
63
+ fun take(id: Int): V? = map.take(id)
64
+
65
+ fun takeIf(
66
+ id: Int,
67
+ shouldTake: Predicate<V>,
68
+ ): V? = map.takeIf(id, shouldTake)
69
+
70
+ fun takeAll(): List<V> = map.takeAll()
71
+ }
@@ -114,6 +114,36 @@ public class RNFBPerfHandleRegistryTest {
114
114
  assertSame(second, registry.get(1));
115
115
  }
116
116
 
117
+ @Test
118
+ public void takeIf_whenMissing_returnsNullWithoutCallingPredicate() {
119
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
120
+ boolean[] called = {false};
121
+ assertNull(
122
+ registry.takeIf(
123
+ 99,
124
+ value -> {
125
+ called[0] = true;
126
+ return true;
127
+ }));
128
+ assertFalse(called[0]);
129
+ }
130
+
131
+ @Test
132
+ public void takeIf_whenPredicateFalse_leavesMapping() throws Exception {
133
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
134
+ registry.put(1, "trace");
135
+ assertNull(registry.takeIf(1, value -> false));
136
+ assertSame("trace", registry.get(1));
137
+ }
138
+
139
+ @Test
140
+ public void takeIf_whenPredicateTrue_removesAndReturns() throws Exception {
141
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
142
+ registry.put(1, "trace");
143
+ assertSame("trace", registry.takeIf(1, value -> value == "trace"));
144
+ assertNull(registry.get(1));
145
+ }
146
+
117
147
  @Test
118
148
  public void get_whenFree_isNull() {
119
149
  RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
 
3
3
  // Generated by genversion.
4
- export const version = '26.4.0';
4
+ export const version = '27.1.0';
5
5
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  import type { FirebaseApp } from '@react-native-firebase/app';
2
2
  import './types/internal';
3
3
  import type { FirebasePerformance, HttpMetric, HttpMethod, PerformanceSettings, PerformanceTrace, ScreenTrace } from './types/perf';
4
- export declare const SDK_VERSION = "26.4.0";
4
+ export declare const SDK_VERSION = "27.1.0";
5
5
  export declare function getPerformance(app?: FirebaseApp): FirebasePerformance;
6
6
  /**
7
7
  * Creates a Performance Monitoring instance and applies optional settings.
@@ -1,2 +1,2 @@
1
- export declare const version = "26.4.0";
1
+ export declare const version = "27.1.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -23,8 +23,18 @@
23
23
  #import "RNFBApp/RNFBHandleMap.h"
24
24
  #endif
25
25
 
26
+ #if __has_include(<RNFBPerf/RNFBPerf-Swift.h>)
27
+ #import <RNFBPerf/RNFBPerf-Swift.h>
28
+ #elif __has_include("RNFBPerf-Swift.h")
29
+ #import "RNFBPerf-Swift.h"
30
+ #elif __has_include("RNFBHandleMapStorage-Swift.inc")
31
+ #import "RNFBHandleMapStorage-Swift.inc"
32
+ #else
33
+ #error "RNFBPerfHandleRegistryStorage Swift interface not found"
34
+ #endif
35
+
26
36
  @interface RNFBPerfHandleRegistry ()
27
- @property(nonatomic, strong) RNFBHandleMap *map;
37
+ @property(nonatomic, strong) RNFBPerfHandleRegistryStorage *storage;
28
38
  @end
29
39
 
30
40
  @implementation RNFBPerfHandleRegistry
@@ -32,37 +42,46 @@
32
42
  - (instancetype)init {
33
43
  self = [super init];
34
44
  if (self) {
35
- _map = [[RNFBHandleMap alloc] init];
45
+ _storage = [[RNFBPerfHandleRegistryStorage alloc] init];
36
46
  }
37
47
  return self;
38
48
  }
39
49
 
40
50
  - (BOOL)put:(id)key value:(id)value error:(NSError **)error {
41
- return [self.map put:key value:value error:error];
51
+ if (![self.storage putOrDiscard:key value:value]) {
52
+ if (error != nil) {
53
+ NSString *message = [NSString stringWithFormat:@"Handle id already registered: %@", key];
54
+ *error = [NSError errorWithDomain:RNFBHandleMapErrorDomain
55
+ code:RNFBHandleMapErrorCollision
56
+ userInfo:@{NSLocalizedDescriptionKey : message}];
57
+ }
58
+ return NO;
59
+ }
60
+ return YES;
42
61
  }
43
62
 
44
63
  - (BOOL)putOrDiscard:(id)key value:(id)value {
45
- return [self.map putIfAbsent:key value:value];
64
+ return [self.storage putOrDiscard:key value:value];
46
65
  }
47
66
 
48
67
  - (id)putReplacing:(id)key value:(id)value {
49
- return [self.map putReplacing:key value:value];
68
+ return [self.storage putReplacing:key value:value];
50
69
  }
51
70
 
52
71
  - (id)get:(id)key {
53
- return [self.map get:key];
72
+ return [self.storage get:key];
54
73
  }
55
74
 
56
75
  - (id)take:(id)key {
57
- return [self.map take:key];
76
+ return [self.storage take:key];
58
77
  }
59
78
 
60
79
  - (id)takeIf:(id)key when:(BOOL (^)(id))condition {
61
- return [self.map takeIf:key when:condition];
80
+ return [self.storage takeIf:key when:condition];
62
81
  }
63
82
 
64
83
  - (NSArray *)takeAll {
65
- return [self.map takeAll];
84
+ return [self.storage takeAll];
66
85
  }
67
86
 
68
87
  @end
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import Foundation
18
+
19
+ #if canImport(RNFBApp)
20
+ import RNFBApp
21
+ #endif
22
+
23
+ /// Perf registry storage. Composes `RNFBHandleMapStorage`; `putOrDiscard` is first-wins
24
+ /// (`putIfAbsent`). Unique `put` collision errors stay on the ObjC façade.
25
+ @objc(RNFBPerfHandleRegistryStorage)
26
+ public final class RNFBPerfHandleRegistryStorage: NSObject {
27
+ private let storage = RNFBHandleMapStorage()
28
+
29
+ @objc(putOrDiscard:value:)
30
+ public func putOrDiscard(_ key: AnyObject, value: AnyObject) -> Bool {
31
+ storage.putIfAbsent(key, value: value)
32
+ }
33
+
34
+ @objc(putReplacing:value:)
35
+ public func putReplacing(_ key: AnyObject, value: AnyObject) -> AnyObject? {
36
+ storage.putReplacing(key, value: value)
37
+ }
38
+
39
+ @objc(get:)
40
+ public func get(_ key: AnyObject) -> AnyObject? {
41
+ storage.get(key)
42
+ }
43
+
44
+ @objc(take:)
45
+ public func take(_ key: AnyObject) -> AnyObject? {
46
+ storage.take(key)
47
+ }
48
+
49
+ @objc(takeIf:when:)
50
+ public func takeIf(_ key: AnyObject, when condition: (AnyObject) -> Bool) -> AnyObject? {
51
+ storage.takeIf(key, when: condition)
52
+ }
53
+
54
+ @objc
55
+ public func takeAll() -> [AnyObject] {
56
+ storage.takeAll()
57
+ }
58
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #import <Foundation/Foundation.h>
19
+ #import <React/RCTBridgeModule.h>
20
+
21
+ #import "RNFBPerfHandleRegistry.h"
22
+
23
+ NS_ASSUME_NONNULL_BEGIN
24
+
25
+ // Plain Objective-C helper (see docs/ios-spm.mdx and
26
+ // okf-bundle/ios-spm-native-imports.md) that owns every call touching
27
+ // Firebase Performance / metric types and the Swift stop appliers /
28
+ // HTTP method mapper for RNFBPerfModule. This keeps RNFBPerfModule.mm free
29
+ // of Firebase imports and `*-Swift.h`: under SPM an Objective-C++ (.mm)
30
+ // TurboModule cannot `@import` Firebase (or parse a Swift-generated header
31
+ // that uses module imports) when C++ modules are disabled (required by
32
+ // React Native's JSI headers). On Mac Catalyst + SPM the upstream wrap
33
+ // target omits the real module — see RNFBPerfHelper.m stubs and
34
+ // https://github.com/firebase/firebase-ios-sdk/pull/16468.
35
+ @interface RNFBPerfHelper : NSObject
36
+
37
+ + (NSDictionary *)constantsDictionary;
38
+
39
+ + (void)setPerformanceCollectionEnabled:(BOOL)enabled
40
+ resolve:(RCTPromiseResolveBlock)resolve
41
+ reject:(RCTPromiseRejectBlock)reject;
42
+
43
+ + (void)setInstrumentationEnabled:(BOOL)enabled
44
+ resolve:(RCTPromiseResolveBlock)resolve
45
+ reject:(RCTPromiseRejectBlock)reject;
46
+
47
+ + (void)startTraceWithId:(NSNumber *)traceId
48
+ identifier:(NSString *)identifier
49
+ inRegistry:(RNFBPerfHandleRegistry *)registry;
50
+
51
+ + (void)stopTraceWithId:(NSNumber *)traceId
52
+ metrics:(nullable NSDictionary *)metrics
53
+ attributes:(nullable NSDictionary *)attributes
54
+ inRegistry:(RNFBPerfHandleRegistry *)registry;
55
+
56
+ + (void)startHttpMetricWithId:(NSNumber *)metricId
57
+ url:(NSString *)url
58
+ httpMethod:(NSString *)httpMethod
59
+ inRegistry:(RNFBPerfHandleRegistry *)registry;
60
+
61
+ + (void)stopHttpMetricWithId:(NSNumber *)metricId
62
+ attributes:(nullable NSDictionary *)attributes
63
+ httpResponseCode:(nullable NSNumber *)httpResponseCode
64
+ requestPayloadSize:(nullable NSNumber *)requestPayloadSize
65
+ responsePayloadSize:(nullable NSNumber *)responsePayloadSize
66
+ responseContentType:(nullable NSString *)responseContentType
67
+ inRegistry:(RNFBPerfHandleRegistry *)registry;
68
+
69
+ @end
70
+
71
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #if __has_include(<Firebase/Firebase.h>)
19
+ #import <Firebase/Firebase.h>
20
+ #define RNFB_PERF_SDK_AVAILABLE 1
21
+ #elif __has_include(<FirebasePerformance/FirebasePerformance.h>)
22
+ #import <FirebaseCore/FirebaseCore.h>
23
+ #import <FirebasePerformance/FirebasePerformance.h>
24
+ #define RNFB_PERF_SDK_AVAILABLE 1
25
+ #elif !TARGET_OS_MACCATALYST
26
+ // SPM on iOS/tvOS when product headers are not visible as includes: use
27
+ // @import in this plain .m (needs -fmodules only). Do not move @import into
28
+ // the .mm TurboModule (that would require -fcxx-modules).
29
+ @import FirebaseCore;
30
+ @import FirebasePerformance;
31
+ #define RNFB_PERF_SDK_AVAILABLE 1
32
+ #else
33
+ // Product headers/modules absent under Mac Catalyst + SPM. Upstream
34
+ // Package.swift omits .macCatalyst from FirebasePerformanceTarget; CocoaPods
35
+ // historically masked this via the Firebase umbrella. Temporary stubs pending
36
+ // https://github.com/firebase/firebase-ios-sdk/pull/16468 (or permanent if
37
+ // upstream declines). When that PR lands, drop the TARGET_OS_MACCATALYST
38
+ // gate and use the @import path on Catalyst too.
39
+ #define RNFB_PERF_SDK_AVAILABLE 0
40
+ #endif
41
+
42
+ #if __has_include(<RNFBPerf/RNFBPerf-Swift.h>)
43
+ #import <RNFBPerf/RNFBPerf-Swift.h>
44
+ #elif __has_include("RNFBPerf-Swift.h")
45
+ #import "RNFBPerf-Swift.h"
46
+ #elif __has_include("RNFBHandleMapStorage-Swift.inc")
47
+ #import "RNFBHandleMapStorage-Swift.inc"
48
+ #else
49
+ #error "RNFBPerf Swift interface not found"
50
+ #endif
51
+
52
+ #import "RNFBApp/RNFBSharedUtils.h"
53
+ #import "RNFBPerfHelper.h"
54
+
55
+ @implementation RNFBPerfHelper
56
+
57
+ #if !RNFB_PERF_SDK_AVAILABLE
58
+ + (void)rejectUnavailable:(RCTPromiseRejectBlock)reject {
59
+ [RNFBSharedUtils rejectPromiseWithUserInfo:reject
60
+ userInfo:(NSMutableDictionary *)@{
61
+ @"code" : @"unsupported",
62
+ @"message" : @"Firebase Performance is not available on "
63
+ @"this platform or dependency configuration.",
64
+ }];
65
+ }
66
+ #endif
67
+
68
+ + (NSDictionary *)constantsDictionary {
69
+ NSMutableDictionary *constants = [NSMutableDictionary new];
70
+ #if RNFB_PERF_SDK_AVAILABLE
71
+ constants[@"isPerformanceCollectionEnabled"] =
72
+ @([FIRPerformance sharedInstance].dataCollectionEnabled);
73
+ constants[@"isInstrumentationEnabled"] =
74
+ @([FIRPerformance sharedInstance].instrumentationEnabled);
75
+ #else
76
+ constants[@"isPerformanceCollectionEnabled"] = @(NO);
77
+ constants[@"isInstrumentationEnabled"] = @(NO);
78
+ #endif
79
+ return constants;
80
+ }
81
+
82
+ + (void)setPerformanceCollectionEnabled:(BOOL)enabled
83
+ resolve:(RCTPromiseResolveBlock)resolve
84
+ reject:(RCTPromiseRejectBlock)reject {
85
+ #if RNFB_PERF_SDK_AVAILABLE
86
+ [FIRPerformance sharedInstance].dataCollectionEnabled = enabled;
87
+ resolve([NSNull null]);
88
+ #else
89
+ (void)enabled;
90
+ (void)resolve;
91
+ [self rejectUnavailable:reject];
92
+ #endif
93
+ }
94
+
95
+ + (void)setInstrumentationEnabled:(BOOL)enabled
96
+ resolve:(RCTPromiseResolveBlock)resolve
97
+ reject:(RCTPromiseRejectBlock)reject {
98
+ #if RNFB_PERF_SDK_AVAILABLE
99
+ [FIRPerformance sharedInstance].instrumentationEnabled = enabled;
100
+ resolve([NSNull null]);
101
+ #else
102
+ (void)enabled;
103
+ (void)resolve;
104
+ [self rejectUnavailable:reject];
105
+ #endif
106
+ }
107
+
108
+ + (void)startTraceWithId:(NSNumber *)traceId
109
+ identifier:(NSString *)identifier
110
+ inRegistry:(RNFBPerfHandleRegistry *)registry {
111
+ #if RNFB_PERF_SDK_AVAILABLE
112
+ FIRTrace *trace = [[FIRPerformance sharedInstance] traceWithName:identifier];
113
+ [trace start];
114
+
115
+ FIRTrace *displaced = [registry putReplacing:traceId value:trace];
116
+ if (displaced != nil) {
117
+ [displaced stop];
118
+ }
119
+ #else
120
+ (void)traceId;
121
+ (void)identifier;
122
+ (void)registry;
123
+ #endif
124
+ }
125
+
126
+ + (void)stopTraceWithId:(NSNumber *)traceId
127
+ metrics:(NSDictionary *)metrics
128
+ attributes:(NSDictionary *)attributes
129
+ inRegistry:(RNFBPerfHandleRegistry *)registry {
130
+ #if RNFB_PERF_SDK_AVAILABLE
131
+ FIRTrace *trace = [registry get:traceId];
132
+ if (trace == nil) {
133
+ return;
134
+ }
135
+
136
+ id<RNFBPerfTraceApplying> traceTarget = (id<RNFBPerfTraceApplying>)trace;
137
+ [RNFBPerfTraceStopApplier applyMetrics:metrics attributes:attributes to:traceTarget];
138
+
139
+ FIRTrace *expected = trace;
140
+ trace = [registry takeIf:traceId
141
+ when:^BOOL(NSObject *value) {
142
+ return value == expected;
143
+ }];
144
+ if (trace != nil) {
145
+ [trace stop];
146
+ }
147
+ #else
148
+ (void)traceId;
149
+ (void)metrics;
150
+ (void)attributes;
151
+ (void)registry;
152
+ #endif
153
+ }
154
+
155
+ + (void)startHttpMetricWithId:(NSNumber *)metricId
156
+ url:(NSString *)url
157
+ httpMethod:(NSString *)httpMethod
158
+ inRegistry:(RNFBPerfHandleRegistry *)registry {
159
+ #if RNFB_PERF_SDK_AVAILABLE
160
+ FIRHTTPMethod method =
161
+ (FIRHTTPMethod)[RNFBPerfHttpMethodMapper httpMethodRawValueForString:httpMethod];
162
+ NSURL *toNSURL = [NSURL URLWithString:url];
163
+
164
+ FIRHTTPMetric *httpMetric = [[FIRHTTPMetric alloc] initWithURL:toNSURL HTTPMethod:method];
165
+ [httpMetric start];
166
+
167
+ FIRHTTPMetric *displaced = [registry putReplacing:metricId value:httpMetric];
168
+ if (displaced != nil) {
169
+ [displaced stop];
170
+ }
171
+ #else
172
+ (void)metricId;
173
+ (void)url;
174
+ (void)httpMethod;
175
+ (void)registry;
176
+ #endif
177
+ }
178
+
179
+ + (void)stopHttpMetricWithId:(NSNumber *)metricId
180
+ attributes:(NSDictionary *)attributes
181
+ httpResponseCode:(NSNumber *)httpResponseCode
182
+ requestPayloadSize:(NSNumber *)requestPayloadSize
183
+ responsePayloadSize:(NSNumber *)responsePayloadSize
184
+ responseContentType:(NSString *)responseContentType
185
+ inRegistry:(RNFBPerfHandleRegistry *)registry {
186
+ #if RNFB_PERF_SDK_AVAILABLE
187
+ FIRHTTPMetric *httpMetric = [registry get:metricId];
188
+ if (httpMetric == nil) {
189
+ return;
190
+ }
191
+
192
+ id<RNFBPerfHttpMetricApplying> httpMetricTarget = (id<RNFBPerfHttpMetricApplying>)httpMetric;
193
+ [RNFBPerfHttpMetricStopApplier applyAttributes:attributes
194
+ httpResponseCode:httpResponseCode
195
+ requestPayloadSize:requestPayloadSize
196
+ responsePayloadSize:responsePayloadSize
197
+ responseContentType:responseContentType
198
+ to:httpMetricTarget];
199
+
200
+ FIRHTTPMetric *expected = httpMetric;
201
+ httpMetric = [registry takeIf:metricId
202
+ when:^BOOL(NSObject *value) {
203
+ return value == expected;
204
+ }];
205
+ if (httpMetric != nil) {
206
+ [httpMetric stop];
207
+ }
208
+ #else
209
+ (void)metricId;
210
+ (void)attributes;
211
+ (void)httpResponseCode;
212
+ (void)requestPayloadSize;
213
+ (void)responsePayloadSize;
214
+ (void)responseContentType;
215
+ (void)registry;
216
+ #endif
217
+ }
218
+
219
+ @end