@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.
- package/CHANGELOG.md +20 -0
- package/RNFBPerf.podspec +6 -1
- package/android/build.gradle +3 -0
- package/android/src/main/java/io/invertase/firebase/perf/RNFBPerfHandleRegistry.kt +71 -0
- package/android/src/test/java/io/invertase/firebase/perf/RNFBPerfHandleRegistryTest.java +30 -0
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/index.d.ts +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/ios/RNFBPerf/RNFBPerfHandleRegistry.m +28 -9
- package/ios/RNFBPerf/RNFBPerfHandleRegistryStorage.swift +58 -0
- package/ios/RNFBPerf/RNFBPerfHelper.h +71 -0
- package/ios/RNFBPerf/RNFBPerfHelper.m +219 -0
- package/ios/RNFBPerf/RNFBPerfHttpMethodMapper.swift +86 -0
- package/ios/RNFBPerf/RNFBPerfHttpMetricStopApplier.swift +87 -0
- package/ios/RNFBPerf/RNFBPerfModule.mm +35 -172
- package/ios/RNFBPerf/RNFBPerfTraceStopApplier.swift +68 -0
- package/ios/RNFBPerf.xcodeproj/project.pbxproj +32 -0
- package/ios/RNFBPerfUnitTests/HostStubs/Firebase/FIRPerformanceHostStub.m +170 -0
- package/ios/RNFBPerfUnitTests/HostStubs/Firebase/Firebase.h +75 -0
- package/ios/RNFBPerfUnitTests/HostStubs/RNFBApp/RNFBSharedUtils.h +12 -0
- package/ios/RNFBPerfUnitTests/HostStubs/RNFBApp/RNFBSharedUtilsHostStub.m +18 -0
- package/ios/RNFBPerfUnitTests/HostStubs/React/RCTBridgeModule.h +10 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfHandleRegistryTests.m +46 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfHelperHostStubTests.m +200 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfHttpMethodMapperFacadeTests.m +52 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfHttpMethodMapperTests.swift +92 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfHttpMetricStopApplierFacadeTests.m +105 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfHttpMetricStopApplierTests.swift +201 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfTraceStopApplierFacadeTests.m +75 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfTraceStopApplierTests.swift +142 -0
- package/ios/RNFBPerfUnitTests/RNFBPerfUnitTests.xcodeproj/project.pbxproj +70 -0
- package/lib/version.ts +1 -1
- package/package.json +4 -4
- 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
|
-
|
|
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
|
|
package/android/build.gradle
CHANGED
|
@@ -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<>();
|
package/dist/module/version.js
CHANGED
|
@@ -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 = "
|
|
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 = "
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
64
|
+
return [self.storage putOrDiscard:key value:value];
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
- (id)putReplacing:(id)key value:(id)value {
|
|
49
|
-
return [self.
|
|
68
|
+
return [self.storage putReplacing:key value:value];
|
|
50
69
|
}
|
|
51
70
|
|
|
52
71
|
- (id)get:(id)key {
|
|
53
|
-
return [self.
|
|
72
|
+
return [self.storage get:key];
|
|
54
73
|
}
|
|
55
74
|
|
|
56
75
|
- (id)take:(id)key {
|
|
57
|
-
return [self.
|
|
76
|
+
return [self.storage take:key];
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
- (id)takeIf:(id)key when:(BOOL (^)(id))condition {
|
|
61
|
-
return [self.
|
|
80
|
+
return [self.storage takeIf:key when:condition];
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
- (NSArray *)takeAll {
|
|
65
|
-
return [self.
|
|
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
|