From 60ad5af1fa035cdd00b80c1d109e48edd3d8c577 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Wed, 21 Jun 2023 10:20:59 +0800 Subject: [PATCH] [go] add network inspector support (#22741) # Why add network inspector support for expo go close ENG-8010 # How integrate the ExpoRequestCdpInterceptor from expo-modules-core. unlike expo-dev-launcher to use hacky solution, we want to enable the network inspector on release mode, so the implementation follows formal way. - on ios, we leverage the `RCTSetCustomNSURLSessionConfigurationProvider` from react-native to create dedicated `URLSessionConfiguration`. - on android, we already have a dedicated okhttp client from expo go. this pr just adds the interceptors. - found image requests are not intercepted, it is because we don't use okhttp for fresco image pipeline. this pr tries to use the okhttp for fresco as react-native. - android expo go has multiple react instances. however, the network inspector currently only support single inspector target to metro-inspector-proxy. as the result, we only limit the current foreground activity to send network inspector events. # Test Plan ncl + expo go to test the network inspector --- .../exp/exponent/ReactNativeStaticHelpers.kt | 4 + .../experience/ReactNativeActivity.kt | 7 ++ .../main/java/host/exp/expoview/Exponent.kt | 15 ++- .../exp/exponent/ExpoNetworkInterceptor.kt | 79 +++++++++++++ ios/Exponent.xcodeproj/project.pbxproj | 8 ++ .../Versioned/Core/EXVersionManager.mm | 14 ++- .../Core/EXVersionedNetworkInterceptor.h | 15 +++ .../Core/EXVersionedNetworkInterceptor.m | 110 ++++++++++++++++++ ios/Podfile | 3 + ios/Podfile.lock | 3 +- 10 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 android/expoview/src/main/java/versioned/host/exp/exponent/ExpoNetworkInterceptor.kt create mode 100644 ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.h create mode 100644 ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.m diff --git a/android/expoview/src/main/java/host/exp/exponent/ReactNativeStaticHelpers.kt b/android/expoview/src/main/java/host/exp/exponent/ReactNativeStaticHelpers.kt index ec6cb33ca6fff..05a816238f3ef 100644 --- a/android/expoview/src/main/java/host/exp/exponent/ReactNativeStaticHelpers.kt +++ b/android/expoview/src/main/java/host/exp/exponent/ReactNativeStaticHelpers.kt @@ -4,6 +4,8 @@ package host.exp.exponent import android.util.Log import com.facebook.proguard.annotations.DoNotStrip import com.facebook.react.common.JavascriptException +import expo.modules.kotlin.devtools.ExpoNetworkInspectOkHttpAppInterceptor +import expo.modules.kotlin.devtools.ExpoNetworkInspectOkHttpNetworkInterceptor import host.exp.exponent.network.ExponentNetwork import host.exp.expoview.Exponent import okhttp3.CookieJar @@ -172,6 +174,8 @@ object ReactNativeStaticHelpers { .writeTimeout(0, TimeUnit.MILLISECONDS) .cookieJar(cookieJar as CookieJar) .cache(exponentNetwork!!.cache) + .addInterceptor(ExpoNetworkInspectOkHttpAppInterceptor()) + .addNetworkInterceptor(ExpoNetworkInspectOkHttpNetworkInterceptor()) return client.build() } } diff --git a/android/expoview/src/main/java/host/exp/exponent/experience/ReactNativeActivity.kt b/android/expoview/src/main/java/host/exp/exponent/experience/ReactNativeActivity.kt index e21e4188df230..db851af5423b5 100644 --- a/android/expoview/src/main/java/host/exp/exponent/experience/ReactNativeActivity.kt +++ b/android/expoview/src/main/java/host/exp/exponent/experience/ReactNativeActivity.kt @@ -71,6 +71,9 @@ abstract class ReactNativeActivity : RNObject("com.facebook.react.ReactInstanceManager") protected var isCrashed = false + protected val networkInterceptor = + RNObject("host.exp.exponent.ExpoNetworkInterceptor") + protected var manifestUrl: String? = null var experienceKey: ExperienceKey? = null protected var sdkVersion: String? = null @@ -287,6 +290,7 @@ abstract class ReactNativeActivity : override fun onPause() { super.onPause() if (reactInstanceManager.isNotNull && !isCrashed) { + networkInterceptor.call("onPause") reactInstanceManager.onHostPause() // TODO: use onHostPause(activity) } @@ -296,6 +300,7 @@ abstract class ReactNativeActivity : super.onResume() if (reactInstanceManager.isNotNull && !isCrashed) { reactInstanceManager.onHostResume(this, this) + networkInterceptor.call("onResume", reactInstanceManager.get()) } } @@ -487,6 +492,8 @@ abstract class ReactNativeActivity : initialProps(bundle) ) + networkInterceptor.loadVersion(sdkVersion).construct().call("start", manifest, mReactInstanceManager.get()) + // Requesting layout to make sure {@link ReactRootView} attached to {@link ReactInstanceManager} // Otherwise, {@link ReactRootView} will hang in {@link waitForReactRootViewToHaveChildrenAndRunCallback}. // Originally react-native will automatically attach after `startReactApplication`. diff --git a/android/expoview/src/main/java/host/exp/expoview/Exponent.kt b/android/expoview/src/main/java/host/exp/expoview/Exponent.kt index 394d55a318f4e..1a51a68285a50 100644 --- a/android/expoview/src/main/java/host/exp/expoview/Exponent.kt +++ b/android/expoview/src/main/java/host/exp/expoview/Exponent.kt @@ -13,11 +13,15 @@ import android.os.StrictMode.ThreadPolicy import android.os.UserManager import com.facebook.common.internal.ByteStreams import com.facebook.drawee.backends.pipeline.Fresco +import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory +import com.facebook.imagepipeline.producers.HttpUrlConnectionNetworkFetcher import com.raizlabs.android.dbflow.config.DatabaseConfig import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager import expo.modules.core.interfaces.Package import expo.modules.core.interfaces.SingletonModule +import expo.modules.kotlin.devtools.ExpoNetworkInspectOkHttpAppInterceptor +import expo.modules.kotlin.devtools.ExpoNetworkInspectOkHttpNetworkInterceptor import expo.modules.manifests.core.Manifest import host.exp.exponent.* import host.exp.exponent.analytics.EXL @@ -40,6 +44,7 @@ import versioned.host.exp.exponent.ExponentPackageDelegate import java.io.* import java.net.URLEncoder import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.TimeUnit import javax.inject.Inject class Exponent private constructor(val context: Context, val application: Application) { @@ -407,7 +412,15 @@ class Exponent private constructor(val context: Context, val application: Applic } try { - Fresco.initialize(context) + val okHttpClient = OkHttpClient.Builder() + .connectTimeout(HttpUrlConnectionNetworkFetcher.HTTP_DEFAULT_TIMEOUT.toLong(), TimeUnit.MILLISECONDS) + .readTimeout(0, TimeUnit.MILLISECONDS) + .writeTimeout(0, TimeUnit.MILLISECONDS) + .addInterceptor(ExpoNetworkInspectOkHttpAppInterceptor()) + .addNetworkInterceptor(ExpoNetworkInspectOkHttpNetworkInterceptor()) + .build() + val imagePipelineConfig = OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient).build() + Fresco.initialize(context, imagePipelineConfig) } catch (e: RuntimeException) { EXL.testError(e) } diff --git a/android/expoview/src/main/java/versioned/host/exp/exponent/ExpoNetworkInterceptor.kt b/android/expoview/src/main/java/versioned/host/exp/exponent/ExpoNetworkInterceptor.kt new file mode 100644 index 0000000000000..665b13c60d680 --- /dev/null +++ b/android/expoview/src/main/java/versioned/host/exp/exponent/ExpoNetworkInterceptor.kt @@ -0,0 +1,79 @@ +// Copyright 2015-present 650 Industries. All rights reserved. + +package versioned.host.exp.exponent + +import com.facebook.react.ReactInstanceManager +import com.facebook.react.bridge.Inspector +import com.facebook.react.devsupport.DevServerHelper +import com.facebook.react.devsupport.DevSupportManagerBase +import com.facebook.react.devsupport.InspectorPackagerConnection +import expo.modules.kotlin.devtools.ExpoRequestCdpInterceptor +import expo.modules.manifests.core.Manifest +import java.io.Closeable + +@Suppress("unused") +class ExpoNetworkInterceptor : Closeable, ExpoRequestCdpInterceptor.Delegate { + private var isStarted = false + private val inspectorPackagerConnection = InspectorPackagerConnectionWrapper() + private var reactInstanceManager: ReactInstanceManager? = null + + fun start(manifest: Manifest, reactInstanceManager: ReactInstanceManager) { + val buildProps = (manifest?.getPluginProperties("expo-build-properties")?.get("android") as? Map<*, *>) + ?.mapKeys { it.key.toString() } + val enableNetworkInspector = buildProps?.get("networkInspector") as? Boolean ?: true + isStarted = enableNetworkInspector + + this.onResume(reactInstanceManager) + } + + fun onResume(reactInstanceManager: ReactInstanceManager) { + if (!isStarted) { + return + } + this.reactInstanceManager = reactInstanceManager + ExpoRequestCdpInterceptor.setDelegate(this) + } + + fun onPause() { + if (!isStarted) { + return + } + ExpoRequestCdpInterceptor.setDelegate(null) + this.reactInstanceManager = null + } + + override fun close() { + this.onPause() + } + + override fun dispatch(event: String) { + reactInstanceManager?.let { + inspectorPackagerConnection.sendWrappedEventToAllPages(it, event) + } + } +} + +/** + * A `InspectorPackagerConnection` wrapper to expose private members with reflection + */ +internal class InspectorPackagerConnectionWrapper { + private val devServerHelperField = DevSupportManagerBase::class.java.getDeclaredField("mDevServerHelper") + private val inspectorPackagerConnectionField = DevServerHelper::class.java.getDeclaredField("mInspectorPackagerConnection") + private val sendWrappedEventMethod = InspectorPackagerConnection::class.java.getDeclaredMethod("sendWrappedEvent", String::class.java, String::class.java) + + init { + devServerHelperField.isAccessible = true + inspectorPackagerConnectionField.isAccessible = true + sendWrappedEventMethod.isAccessible = true + } + + fun sendWrappedEventToAllPages(reactInstanceManager: ReactInstanceManager, event: String) { + val devServerHelper = devServerHelperField[reactInstanceManager.devSupportManager] + val inspectorPackagerConnection = inspectorPackagerConnectionField[devServerHelper] as? InspectorPackagerConnection + for (page in Inspector.getPages()) { + if (!page.title.contains("Reanimated")) { + sendWrappedEventMethod.invoke(inspectorPackagerConnection, page.id.toString(), event) + } + } + } +} diff --git a/ios/Exponent.xcodeproj/project.pbxproj b/ios/Exponent.xcodeproj/project.pbxproj index b3d8d39d6e648..6d5937b4d80ca 100644 --- a/ios/Exponent.xcodeproj/project.pbxproj +++ b/ios/Exponent.xcodeproj/project.pbxproj @@ -125,6 +125,8 @@ 8353B820277A17FC00AFCBDA /* EXStandaloneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8353B81E277A17FB00AFCBDA /* EXStandaloneViewController.m */; }; 8353B821277A17FC00AFCBDA /* EXStandaloneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8353B81E277A17FB00AFCBDA /* EXStandaloneViewController.m */; }; 837259A9280671D200E204C1 /* AIRMapUrlTileCachedOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A35BDC646C64B7988CCD0CA /* AIRMapUrlTileCachedOverlay.m */; }; + 837A38252A20D7090046BD8E /* EXVersionedNetworkInterceptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 837A38242A20D7090046BD8E /* EXVersionedNetworkInterceptor.m */; }; + 837A38262A20D7090046BD8E /* EXVersionedNetworkInterceptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 837A38242A20D7090046BD8E /* EXVersionedNetworkInterceptor.m */; }; 83D00C72292CABD400CCEFAB /* EXTextDirectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F885A328FEC26000CFD75C /* EXTextDirectionController.swift */; }; 84713BFB28584A0100E86B56 /* EXErrorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84713BFA28584A0100E86B56 /* EXErrorView.xib */; }; 84713BFC28584A0100E86B56 /* EXErrorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84713BFA28584A0100E86B56 /* EXErrorView.xib */; }; @@ -745,6 +747,8 @@ 80598B49D2DB4720B1935D89 /* RNSharedElementNodeManager.m */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.objc; path = RNSharedElementNodeManager.m; sourceTree = ""; }; 8353B81E277A17FB00AFCBDA /* EXStandaloneViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EXStandaloneViewController.m; sourceTree = ""; }; 8353B81F277A17FC00AFCBDA /* EXStandaloneViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXStandaloneViewController.h; sourceTree = ""; }; + 837A38232A20D6730046BD8E /* EXVersionedNetworkInterceptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EXVersionedNetworkInterceptor.h; sourceTree = ""; }; + 837A38242A20D7090046BD8E /* EXVersionedNetworkInterceptor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EXVersionedNetworkInterceptor.m; sourceTree = ""; }; 84713BFA28584A0100E86B56 /* EXErrorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EXErrorView.xib; sourceTree = ""; }; 8746D75D24D04B2300BFAD22 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 8764788C270F1AF30076CA5F /* EXAppLoadingProgressWindowViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXAppLoadingProgressWindowViewController.swift; sourceTree = ""; }; @@ -1697,6 +1701,8 @@ B5FB74241FF6DADB001C764B /* ScopedModule */, 31DBC6AA20B5B4C60049A476 /* UniversalModules */, B5FB73FA1FF6DADB001C764B /* EXUnversioned.h */, + 837A38232A20D6730046BD8E /* EXVersionedNetworkInterceptor.h */, + 837A38242A20D7090046BD8E /* EXVersionedNetworkInterceptor.m */, B5FB73FB1FF6DADB001C764B /* EXVersionManager.h */, B5FB73FC1FF6DADB001C764B /* EXVersionManager.mm */, ); @@ -2808,6 +2814,7 @@ 31AD99F02285B51100F19090 /* AIRGoogleMap.m in Sources */, 31AD9A412285B53100F19090 /* AIRMapMarkerManager.m in Sources */, B5ADEE951F7DB4E000C88D2F /* EXBuildConstants.m in Sources */, + 837A38252A20D7090046BD8E /* EXVersionedNetworkInterceptor.m in Sources */, 31AD9A4D2285B53100F19090 /* RCTConvert+AirMap.m in Sources */, 8767F97624D19FA7009F9372 /* EXHomeAppSplashScreenViewProvider.m in Sources */, 2168B25C23E3058600A94C0D /* EXScopedFirebaseCore.m in Sources */, @@ -3052,6 +3059,7 @@ F14218B0262CB68600BB97E6 /* AIRGoogleMapOverlayManager.m in Sources */, F14218B1262CB68600BB97E6 /* EXKernelDevKeyCommands.m in Sources */, F14218B2262CB68600BB97E6 /* AIRMapUrlTileManager.m in Sources */, + 837A38262A20D7090046BD8E /* EXVersionedNetworkInterceptor.m in Sources */, 2D5265EC294998B5001BB2BB /* EXHomeLoader.m in Sources */, F14218B3262CB68600BB97E6 /* EXKernelAppRegistry.m in Sources */, F14218B4262CB68600BB97E6 /* EXErrorRecoveryManager.m in Sources */, diff --git a/ios/Exponent/Versioned/Core/EXVersionManager.mm b/ios/Exponent/Versioned/Core/EXVersionManager.mm index 25e6229631813..e3946b6689a4a 100644 --- a/ios/Exponent/Versioned/Core/EXVersionManager.mm +++ b/ios/Exponent/Versioned/Core/EXVersionManager.mm @@ -5,6 +5,7 @@ #import "EXDisabledDevLoadingView.h" #import "EXDisabledDevMenu.h" #import "EXDisabledRedBox.h" +#import "EXVersionedNetworkInterceptor.h" #import "EXVersionManager.h" #import "EXScopedBridgeModule.h" #import "EXStatusBarManager.h" @@ -96,6 +97,7 @@ @interface EXVersionManager () @property (nonatomic, strong) NSDictionary *params; @property (nonatomic, strong) EXManifestsManifest *manifest; @property (nonatomic, strong) RCTTurboModuleManager *turboModuleManager; +@property (nonatomic, strong) EXVersionedNetworkInterceptor *networkInterceptor; @end @@ -143,7 +145,13 @@ - (void)bridgeWillStartLoading:(id)bridge NSURL *bundleURL = [bridge bundleURL]; NSString *packagerServerHostPort = [NSString stringWithFormat:@"%@:%@", bundleURL.host, bundleURL.port]; [[RCTPackagerConnection sharedPackagerConnection] reconnect:packagerServerHostPort]; - [RCTInspectorDevServerHelper connectWithBundleURL:bundleURL]; + RCTInspectorPackagerConnection *inspectorPackagerConnection = [RCTInspectorDevServerHelper connectWithBundleURL:bundleURL]; + + NSDictionary *buildProps = [self.manifest getPluginPropertiesWithPackageName:@"expo-build-properties"]; + NSNumber *enableNetworkInterceptor = [[buildProps objectForKey:@"ios"] objectForKey:@"unstable_networkInspector"]; + if (enableNetworkInterceptor == nil || [enableNetworkInterceptor boolValue] != NO) { + self.networkInterceptor = [[EXVersionedNetworkInterceptor alloc] initWithRCTInspectorPackagerConnection:inspectorPackagerConnection]; + } } // Manually send a "start loading" notif, since the real one happened uselessly inside the RCTBatchedBridge constructor @@ -161,7 +169,9 @@ - (void)bridgeFinishedLoading:(id)bridge }]; } -- (void)invalidate {} +- (void)invalidate { + self.networkInterceptor = nil; +} - (NSDictionary *)devMenuItemsForBridge:(id)bridge { diff --git a/ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.h b/ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.h new file mode 100644 index 0000000000000..ec7fb0a931641 --- /dev/null +++ b/ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.h @@ -0,0 +1,15 @@ +// Copyright 2015-present 650 Industries. All rights reserved. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class RCTInspectorPackagerConnection; + +@interface EXVersionedNetworkInterceptor : NSObject + +- (instancetype)initWithRCTInspectorPackagerConnection:(RCTInspectorPackagerConnection *)inspectorPackgerConnection; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.m b/ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.m new file mode 100644 index 0000000000000..5a709e6b33fe4 --- /dev/null +++ b/ios/Exponent/Versioned/Core/EXVersionedNetworkInterceptor.m @@ -0,0 +1,110 @@ +// Copyright 2015-present 650 Industries. All rights reserved. + +#import "EXVersionedNetworkInterceptor.h" + +#import +#import +#import +#import + +#import "Expo_Go-Swift.h" +#import "ExpoModulesCore-Swift.h" + +#pragma mark - RCTInspectorPackagerConnection category interface + +@interface RCTInspectorPackagerConnection(sendWrappedEventToAllPages) + +- (BOOL)isReadyToSend; +- (void)sendWrappedEventToAllPages:(NSString *)event; + +@end + +#pragma mark - + +@interface EXVersionedNetworkInterceptor () + +@property (nonatomic, strong) RCTInspectorPackagerConnection *inspectorPackgerConnection; + +@end + +@implementation EXVersionedNetworkInterceptor + +- (instancetype)initWithRCTInspectorPackagerConnection:(RCTInspectorPackagerConnection *)inspectorPackgerConnection +{ + if (self = [super init]) { + self.inspectorPackgerConnection = inspectorPackgerConnection; + [EXRequestCdpInterceptor.shared setDelegate:self]; + + Class requestInterceptorClass = [EXRequestInterceptorProtocol class]; + RCTSetCustomNSURLSessionConfigurationProvider(^{ + NSURLSessionConfiguration *urlSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; + NSMutableArray *protocolClasses = [urlSessionConfiguration.protocolClasses mutableCopy]; + if (![protocolClasses containsObject:requestInterceptorClass]) { + [protocolClasses insertObject:requestInterceptorClass atIndex:0]; + } + urlSessionConfiguration.protocolClasses = protocolClasses; + + [urlSessionConfiguration setHTTPShouldSetCookies:YES]; + [urlSessionConfiguration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; + [urlSessionConfiguration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; + return urlSessionConfiguration; + }); + } + return self; +} + +- (void)dealloc +{ + [EXRequestCdpInterceptor.shared setDelegate:nil]; +} + +#pragma mark - EXRequestCdpInterceptorDelegate implementations + +- (void)dispatch:(NSString * _Nonnull)event { + [self.inspectorPackgerConnection sendWrappedEventToAllPages:event]; +} + +@end + +#pragma mark - RCTInspectorPackagerConnection category + +@interface RCTInspectorPackagerConnection(sendWrappedEventToAllPages) + +- (BOOL)isReadyToSend; +- (void)sendWrappedEventToAllPages:(NSString *)event; + +@end + +#pragma mark - RCTInspectorPackagerConnection category implementation + +@implementation RCTInspectorPackagerConnection(sendWrappedEventToAllPages) + +- (BOOL)isReadyToSend +{ + if ([self isConnected]) { + return YES; + } + + SRWebSocket *websocket = [self valueForKey:@"_webSocket"]; + return websocket.readyState == SR_OPEN; +} + +- (void)sendWrappedEventToAllPages:(NSString *)event +{ + if (![self isReadyToSend]) { + return; + } + + SEL selector = NSSelectorFromString(@"sendWrappedEvent:message:"); + if ([self respondsToSelector:selector]) { + IMP sendWrappedEventIMP = [self methodForSelector:selector]; + void (*functor)(id, SEL, NSString *, NSString *) = (void *)sendWrappedEventIMP; + for (RCTInspectorPage* page in RCTInspector.pages) { + if (![page.title containsString:@"Reanimated"]) { + functor(self, selector, [@(page.id) stringValue], event); + } + } + } +} + +@end diff --git a/ios/Podfile b/ios/Podfile index c214d085beea6..b21527cf70cdc 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -18,6 +18,9 @@ abstract_target 'Expo Go' do pod 'JKBigInteger', :podspec => 'vendored/common/JKBigInteger.podspec.json' pod 'MBProgressHUD', '~> 1.2.0' + # transitive dependency of React-Core and we use it to get the `RCTInspectorPackagerConnection` state + pod 'SocketRocket' + # Required by firebase core versions 9.x / 10.x (included with SDK 47) # See https://github.com/invertase/react-native-firebase/issues/6332#issuecomment-1189734581 pod 'FirebaseCore', :modular_headers => true diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 02a44555a316f..70bffe47894fb 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2660,6 +2660,7 @@ DEPENDENCIES: - RNReanimated (from `./vendored/unversioned/react-native-reanimated`) - RNScreens (from `./vendored/unversioned/react-native-screens`) - RNSVG (from `./vendored/unversioned/react-native-svg`) + - SocketRocket - "stripe-react-native (from `./vendored/unversioned/@stripe/stripe-react-native`)" - UMAppLoader (from `../packages/unimodules-app-loader/ios`) - Yoga (from `../react-native-lab/react-native/packages/react-native/ReactCommon/yoga`) @@ -3799,6 +3800,6 @@ SPEC CHECKSUMS: Yoga: 258bd5f6f188432f18cc3f854497f1cf6a0f21c1 ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: fc5d3a6d03f638818036d761cd8cb82ec403a6ea +PODFILE CHECKSUM: e93fdba4b82928a5067623f67dca0603beb4d28e COCOAPODS: 1.12.1