mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
RCTCxxInspectorPackagerConnection (#42037)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42037 Creates an Objective-C wrapper around the C++ version of `InspectorPackagerConnection` (introduced in D52134592), and uses it in React Native iOS apps (behind an internal flag that is off by default). In future work, the flag will be turned on by default, then deleted, and eventually the legacy `RCTInspectorPackagerConnection` code will be deleted from React Native. Changelog: [Internal] Reviewed By: huntie Differential Revision: D52225495 fbshipit-source-id: f1b9657ef0d665cf7892c15c34c5104e2777ec43
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a9a736f2ad
commit
e28d15fca5
@@ -104,6 +104,7 @@ Pod::Spec.new do |s|
|
||||
ss.dependency "React-Core/Default", version
|
||||
ss.dependency "React-Core/RCTWebSocket", version
|
||||
ss.dependency "React-jsinspector", version
|
||||
ss.private_header_files = "React/Inspector/RCTCxx*.h"
|
||||
end
|
||||
|
||||
s.subspec "RCTWebSocket" do |ss|
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
@interface RCTInspectorDevServerHelper : NSObject
|
||||
|
||||
+ (RCTInspectorPackagerConnection *)connectWithBundleURL:(NSURL *)bundleURL;
|
||||
+ (id<RCTInspectorPackagerConnectionProtocol>)connectWithBundleURL:(NSURL *)bundleURL;
|
||||
+ (void)disableDebugger;
|
||||
+ (void)openDebugger:(NSURL *)bundleURL withErrorMessage:(NSString *)errorMessage;
|
||||
@end
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
#import <React/RCTLog.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTCxxInspectorPackagerConnection.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTInspectorPackagerConnection.h>
|
||||
|
||||
#import <CommonCrypto/CommonCrypto.h>
|
||||
#import <jsinspector-modern/InspectorFlags.h>
|
||||
|
||||
static NSString *const kDebuggerMsgDisable = @"{ \"id\":1,\"method\":\"Debugger.disable\" }";
|
||||
|
||||
@@ -107,7 +109,7 @@ static NSURL *getInspectorDeviceUrl(NSURL *bundleURL)
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
static NSMutableDictionary<NSString *, RCTInspectorPackagerConnection *> *socketConnections = nil;
|
||||
static NSMutableDictionary<NSString *, id<RCTInspectorPackagerConnectionProtocol>> *socketConnections = nil;
|
||||
|
||||
static void sendEventToAllConnections(NSString *event)
|
||||
{
|
||||
@@ -146,7 +148,7 @@ static void sendEventToAllConnections(NSString *event)
|
||||
sendEventToAllConnections(kDebuggerMsgDisable);
|
||||
}
|
||||
|
||||
+ (RCTInspectorPackagerConnection *)connectWithBundleURL:(NSURL *)bundleURL
|
||||
+ (id<RCTInspectorPackagerConnectionProtocol>)connectWithBundleURL:(NSURL *)bundleURL
|
||||
{
|
||||
NSURL *inspectorURL = getInspectorDeviceUrl(bundleURL);
|
||||
|
||||
@@ -158,9 +160,14 @@ static void sendEventToAllConnections(NSString *event)
|
||||
}
|
||||
|
||||
NSString *key = [inspectorURL absoluteString];
|
||||
RCTInspectorPackagerConnection *connection = socketConnections[key];
|
||||
id<RCTInspectorPackagerConnectionProtocol> connection = socketConnections[key];
|
||||
if (!connection || !connection.isConnected) {
|
||||
connection = [[RCTInspectorPackagerConnection alloc] initWithURL:inspectorURL];
|
||||
if (facebook::react::jsinspector_modern::InspectorFlags::getInstance().getEnableCxxInspectorPackagerConnection()) {
|
||||
connection = [[RCTCxxInspectorPackagerConnection alloc] initWithURL:inspectorURL];
|
||||
} else {
|
||||
connection = [[RCTInspectorPackagerConnection alloc] initWithURL:inspectorURL];
|
||||
}
|
||||
|
||||
socketConnections[key] = connection;
|
||||
[connection connect];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import "RCTInspectorPackagerConnection.h"
|
||||
|
||||
#if RCT_DEV || RCT_REMOTE_PROFILE
|
||||
|
||||
@interface RCTCxxInspectorPackagerConnection : NSObject <RCTInspectorPackagerConnectionProtocol>
|
||||
@end
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTInspectorPackagerConnection.h>
|
||||
|
||||
#if RCT_DEV || RCT_REMOTE_PROFILE
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTInspector.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTUtils.h>
|
||||
#import <SocketRocket/SRWebSocket.h>
|
||||
#import <jsinspector-modern/InspectorPackagerConnection.h>
|
||||
|
||||
#import <chrono>
|
||||
#import <memory>
|
||||
|
||||
#import "RCTCxxInspectorPackagerConnection.h"
|
||||
#import "RCTCxxInspectorPackagerConnectionDelegate.h"
|
||||
#import "RCTCxxInspectorWebSocketAdapter.h"
|
||||
|
||||
using namespace facebook::react::jsinspector_modern;
|
||||
@interface RCTCxxInspectorPackagerConnection () {
|
||||
std::unique_ptr<InspectorPackagerConnection> _cxxImpl;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation RCTCxxInspectorPackagerConnection
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_cxxImpl = std::make_unique<InspectorPackagerConnection>(
|
||||
[url absoluteString].UTF8String,
|
||||
[[NSBundle mainBundle] bundleIdentifier].UTF8String,
|
||||
std::make_unique<RCTCxxInspectorPackagerConnectionDelegate>());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sendEventToAllConnections:(NSString *)event
|
||||
{
|
||||
_cxxImpl->sendEventToAllConnections(event.UTF8String);
|
||||
}
|
||||
|
||||
- (bool)isConnected
|
||||
{
|
||||
return _cxxImpl->isConnected();
|
||||
}
|
||||
|
||||
- (void)connect
|
||||
{
|
||||
_cxxImpl->connect();
|
||||
}
|
||||
|
||||
- (void)closeQuietly
|
||||
{
|
||||
_cxxImpl->closeQuietly();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTCxxInspectorWebSocketAdapter.h"
|
||||
|
||||
#import <jsinspector-modern/InspectorPackagerConnection.h>
|
||||
|
||||
#import <chrono>
|
||||
#import <memory>
|
||||
#import <string>
|
||||
|
||||
namespace facebook::react::jsinspector_modern {
|
||||
/**
|
||||
* Glue between C++ and Objective-C for InspectorPackagerConnectionDelegate.
|
||||
*/
|
||||
class RCTCxxInspectorPackagerConnectionDelegate
|
||||
: public InspectorPackagerConnectionDelegate {
|
||||
class WebSocket : public IWebSocket {
|
||||
public:
|
||||
WebSocket(RCTCxxInspectorWebSocketAdapter* adapter);
|
||||
virtual void send(std::string_view message) override;
|
||||
virtual ~WebSocket() override;
|
||||
|
||||
private:
|
||||
RCTCxxInspectorWebSocketAdapter* _adapter;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual std::unique_ptr<IWebSocket> connectWebSocket(
|
||||
const std::string& url,
|
||||
std::weak_ptr<IWebSocketDelegate> delegate) override;
|
||||
|
||||
virtual void scheduleCallback(
|
||||
std::function<void(void)> callback,
|
||||
std::chrono::milliseconds delayMs) override;
|
||||
};
|
||||
} // namespace facebook::react::jsinspector_modern
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTCxxInspectorPackagerConnectionDelegate.h"
|
||||
|
||||
#import <dispatch/dispatch.h>
|
||||
|
||||
namespace facebook::react::jsinspector_modern {
|
||||
RCTCxxInspectorPackagerConnectionDelegate::WebSocket::WebSocket(RCTCxxInspectorWebSocketAdapter *adapter)
|
||||
: _adapter(adapter)
|
||||
{
|
||||
}
|
||||
|
||||
void RCTCxxInspectorPackagerConnectionDelegate::WebSocket::send(std::string_view message)
|
||||
{
|
||||
[_adapter send:message];
|
||||
}
|
||||
|
||||
RCTCxxInspectorPackagerConnectionDelegate::WebSocket::~WebSocket()
|
||||
{
|
||||
[_adapter close];
|
||||
}
|
||||
|
||||
std::unique_ptr<IWebSocket> RCTCxxInspectorPackagerConnectionDelegate::connectWebSocket(
|
||||
const std::string &url,
|
||||
std::weak_ptr<IWebSocketDelegate> delegate)
|
||||
{
|
||||
auto *adapter = [[RCTCxxInspectorWebSocketAdapter alloc] initWithURL:url delegate:delegate];
|
||||
return std::make_unique<WebSocket>(adapter);
|
||||
}
|
||||
|
||||
void RCTCxxInspectorPackagerConnectionDelegate::scheduleCallback(
|
||||
std::function<void(void)> callback,
|
||||
std::chrono::milliseconds delayMs)
|
||||
{
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delayMs.count() * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
|
||||
callback();
|
||||
});
|
||||
}
|
||||
} // namespace facebook::react::jsinspector_modern
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <jsinspector-modern/InspectorPackagerConnection.h>
|
||||
#import <memory>
|
||||
#import <string>
|
||||
|
||||
@interface RCTCxxInspectorWebSocketAdapter : NSObject
|
||||
- (instancetype)initWithURL:(const std::string &)url
|
||||
delegate:(std::weak_ptr<facebook::react::jsinspector_modern::IWebSocketDelegate>)delegate;
|
||||
- (void)send:(std::string_view)message;
|
||||
- (void)close;
|
||||
@end
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTInspectorPackagerConnection.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTInspector.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTUtils.h>
|
||||
#import <SocketRocket/SRWebSocket.h>
|
||||
#import <jsinspector-modern/InspectorPackagerConnection.h>
|
||||
#import <memory>
|
||||
#import "RCTCxxInspectorWebSocketAdapter.h"
|
||||
|
||||
using namespace facebook::react::jsinspector_modern;
|
||||
|
||||
namespace {
|
||||
NSString *NSStringFromUTF8StringView(std::string_view view)
|
||||
{
|
||||
return [[NSString alloc] initWithBytes:(const char *)view.data() length:view.size() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
}
|
||||
@interface RCTCxxInspectorWebSocketAdapter () <SRWebSocketDelegate> {
|
||||
std::weak_ptr<IWebSocketDelegate> _delegate;
|
||||
SRWebSocket *_webSocket;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation RCTCxxInspectorWebSocketAdapter
|
||||
- (instancetype)initWithURL:(const std::string &)url delegate:(std::weak_ptr<IWebSocketDelegate>)delegate
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_delegate = delegate;
|
||||
_webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:NSStringFromUTF8StringView(url)]];
|
||||
_webSocket.delegate = self;
|
||||
[_webSocket open];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)send:(std::string_view)message
|
||||
{
|
||||
__weak RCTCxxInspectorWebSocketAdapter *weakSelf = self;
|
||||
NSString *messageStr = NSStringFromUTF8StringView(message);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
RCTCxxInspectorWebSocketAdapter *strongSelf = weakSelf;
|
||||
if (strongSelf) {
|
||||
[strongSelf->_webSocket send:messageStr];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)close
|
||||
{
|
||||
[_webSocket closeWithCode:1000 reason:@"End of session"];
|
||||
}
|
||||
|
||||
- (void)webSocket:(__unused SRWebSocket *)webSocket didFailWithError:(NSError *)error
|
||||
{
|
||||
if (auto delegate = _delegate.lock()) {
|
||||
delegate->didFailWithError([error code], [error description].UTF8String);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webSocket:(__unused SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)message
|
||||
{
|
||||
if (auto delegate = _delegate.lock()) {
|
||||
delegate->didReceiveMessage([message UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webSocket:(__unused SRWebSocket *)webSocket
|
||||
didCloseWithCode:(__unused NSInteger)code
|
||||
reason:(__unused NSString *)reason
|
||||
wasClean:(__unused BOOL)wasClean
|
||||
{
|
||||
if (auto delegate = _delegate.lock()) {
|
||||
delegate->didClose();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#if RCT_DEV || RCT_REMOTE_PROFILE
|
||||
|
||||
#include <jsinspector-modern/InspectorInterfaces.h>
|
||||
#import <jsinspector-modern/InspectorInterfaces.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTInspectorPackagerConnection.h>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#if RCT_DEV || RCT_REMOTE_PROFILE
|
||||
|
||||
@interface RCTInspectorPackagerConnection : NSObject
|
||||
@protocol RCTInspectorPackagerConnectionProtocol <NSObject>
|
||||
- (instancetype)initWithURL:(NSURL *)url;
|
||||
|
||||
- (bool)isConnected;
|
||||
@@ -19,6 +19,9 @@
|
||||
- (void)sendEventToAllConnections:(NSString *)event;
|
||||
@end
|
||||
|
||||
@interface RCTInspectorPackagerConnection : NSObject <RCTInspectorPackagerConnectionProtocol>
|
||||
@end
|
||||
|
||||
@interface RCTInspectorRemoteConnection : NSObject
|
||||
- (void)onMessage:(NSString *)message;
|
||||
- (void)onDisconnect;
|
||||
|
||||
@@ -30,7 +30,7 @@ Pod::Spec.new do |s|
|
||||
s.platforms = min_supported_versions
|
||||
s.source = source
|
||||
s.source_files = "*.{cpp,h}"
|
||||
s.header_dir = 'jsinspector'
|
||||
s.header_dir = 'jsinspector-modern'
|
||||
s.compiler_flags = folly_compiler_flags
|
||||
s.pod_target_xcconfig = {
|
||||
"HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"",
|
||||
|
||||
Reference in New Issue
Block a user