Make RCTWebSocketModule TurboModule-compatible

Summary:
Changelog:
[iOS][Added] - Make RCTWebSocketModule TurboModule-compatible

Reviewed By: PeteTheHeat

Differential Revision: D18353766

fbshipit-source-id: fde0f6593dd203ab3dcb8f9cf40012ba4761d6ba
This commit is contained in:
Ramanpreet Nara 2019-11-08 14:08:11 -08:00 коммит произвёл Facebook Github Bot
Родитель 1b2992e8b3
Коммит d73ae1baa3
11 изменённых файлов: 68 добавлений и 60 удалений

Просмотреть файл

@ -2613,12 +2613,6 @@ namespace facebook {
} // namespace react
} // namespace facebook
@implementation RCTCxxConvert (NativeWebSocketModule_SpecConnectOptionsHeaders)
+ (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptionsHeaders:(id)json
{
return facebook::react::managedPointer<JS::NativeWebSocketModule::SpecConnectOptionsHeaders>(json);
}
@end
@implementation RCTCxxConvert (NativeWebSocketModule_SpecConnectOptions)
+ (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptions:(id)json
{
@ -2634,11 +2628,11 @@ namespace facebook {
}
static facebook::jsi::Value __hostFunction_NativeWebSocketModuleSpecJSI_send(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "send", @selector(send:socketID:), args, count);
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "send", @selector(send:forSocketID:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeWebSocketModuleSpecJSI_sendBinary(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "sendBinary", @selector(sendBinary:socketID:), args, count);
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "sendBinary", @selector(sendBinary:forSocketID:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeWebSocketModuleSpecJSI_ping(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {

Просмотреть файл

@ -2697,26 +2697,10 @@ namespace facebook {
} // namespace react
} // namespace facebook
namespace JS {
namespace NativeWebSocketModule {
struct SpecConnectOptionsHeaders {
NSString *origin() const;
SpecConnectOptionsHeaders(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeWebSocketModule_SpecConnectOptionsHeaders)
+ (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptionsHeaders:(id)json;
@end
namespace JS {
namespace NativeWebSocketModule {
struct SpecConnectOptions {
folly::Optional<JS::NativeWebSocketModule::SpecConnectOptionsHeaders> headers() const;
id<NSObject> _Nullable headers() const;
SpecConnectOptions(NSDictionary *const v) : _v(v) {}
private:
@ -2735,9 +2719,9 @@ namespace JS {
options:(JS::NativeWebSocketModule::SpecConnectOptions &)options
socketID:(double)socketID;
- (void)send:(NSString *)message
socketID:(double)socketID;
forSocketID:(double)forSocketID;
- (void)sendBinary:(NSString *)base64String
socketID:(double)socketID;
forSocketID:(double)forSocketID;
- (void)ping:(double)socketID;
- (void)close:(double)code
reason:(NSString *)reason
@ -3738,13 +3722,8 @@ inline JS::NativeUIManager::Constants::Builder::Builder(const Input i) : _factor
inline JS::NativeUIManager::Constants::Builder::Builder(Constants i) : _factory(^{
return i.unsafeRawValue();
}) {}
inline NSString *JS::NativeWebSocketModule::SpecConnectOptionsHeaders::origin() const
{
id const p = _v[@"origin"];
return RCTBridgingToString(p);
}
inline folly::Optional<JS::NativeWebSocketModule::SpecConnectOptionsHeaders> JS::NativeWebSocketModule::SpecConnectOptions::headers() const
inline id<NSObject> _Nullable JS::NativeWebSocketModule::SpecConnectOptions::headers() const
{
id const p = _v[@"headers"];
return (p == nil ? folly::none : folly::make_optional(JS::NativeWebSocketModule::SpecConnectOptionsHeaders(p)));
return p;
}

Просмотреть файл

@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @flow
* @format
*/
@ -17,11 +17,11 @@ export interface Spec extends TurboModule {
+connect: (
url: string,
protocols: ?Array<string>,
options: ?{headers?: {origin?: string}},
options: {|headers?: Object|},
socketID: number,
) => void;
+send: (message: string, socketID: number) => void;
+sendBinary: (base64String: string, socketID: number) => void;
+send: (message: string, forSocketID: number) => void;
+sendBinary: (base64String: string, forSocketID: number) => void;
+ping: (socketID: number) => void;
+close: (code: number, reason: string, socketID: number) => void;

Просмотреть файл

@ -99,6 +99,12 @@ rn_apple_library(
) + react_module_plugin_providers(
name = "TVNavigationEventEmitter",
native_class_func = "RCTTVNavigationEventEmitterCls",
) + react_module_plugin_providers(
name = "WebSocketExecutor",
native_class_func = "RCTWebSocketExecutorCls",
) + react_module_plugin_providers(
name = "WebSocketModule",
native_class_func = "RCTWebSocketModuleCls",
),
plugins_header = "FBCoreModulesPlugins.h",
preprocessor_flags = OBJC_ARC_PREPROCESSOR_FLAGS + get_debug_preprocessor_flags() + rn_extra_build_flags() + [

Просмотреть файл

@ -49,6 +49,8 @@ Class RCTDevMenuCls(void) __attribute__((used));
Class RCTDevSettingsCls(void) __attribute__((used));
Class RCTRedBoxCls(void) __attribute__((used));
Class RCTTVNavigationEventEmitterCls(void) __attribute__((used));
Class RCTWebSocketExecutorCls(void) __attribute__((used));
Class RCTWebSocketModuleCls(void) __attribute__((used));
#ifdef __cplusplus
}

Просмотреть файл

@ -38,6 +38,8 @@ Class RCTCoreModulesClassProvider(const char *name) {
{"DevSettings", RCTDevSettingsCls},
{"RedBox", RCTRedBoxCls},
{"TVNavigationEventEmitter", RCTTVNavigationEventEmitterCls},
{"WebSocketExecutor", RCTWebSocketExecutorCls},
{"WebSocketModule", RCTWebSocketModuleCls},
};
auto p = sCoreModuleClassMap.find(name);

Просмотреть файл

@ -13,14 +13,17 @@
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>
#import <React/RCTSRWebSocket.h>
#import <ReactCommon/RCTTurboModule.h>
#import "CoreModulesPlugins.h"
#if RCT_DEV // Debug executors are only supported in dev mode
typedef void (^RCTWSMessageCallback)(NSError *error, NSDictionary<NSString *, id> *reply);
@interface RCTWebSocketExecutor () <RCTSRWebSocketDelegate>
@interface RCTWebSocketExecutor () <RCTSRWebSocketDelegate, RCTTurboModule>
@end
@ -271,3 +274,11 @@ RCT_EXPORT_MODULE()
@end
#endif
Class RCTWebSocketExecutorCls(void) {
#if RCT_DEV
return RCTWebSocketExecutor.class;
#else
return nil;
#endif
}

Просмотреть файл

@ -9,11 +9,13 @@
#import <objc/runtime.h>
#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/RCTConvert.h>
#import <React/RCTUtils.h>
#import <React/RCTSRWebSocket.h>
#import "CoreModulesPlugins.h"
@implementation RCTSRWebSocket (React)
- (NSNumber *)reactTag
@ -28,7 +30,7 @@
@end
@interface RCTWebSocketModule () <RCTSRWebSocketDelegate>
@interface RCTWebSocketModule () <RCTSRWebSocketDelegate, NativeWebSocketModuleSpec>
@end
@ -62,7 +64,7 @@ RCT_EXPORT_MODULE()
}
}
RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols options:(NSDictionary *)options socketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols options:(JS::NativeWebSocketModule::SpecConnectOptions &)options socketID:(double)socketID)
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
@ -79,45 +81,48 @@ RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols options:(N
request.allHTTPHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
// Load supplied headers
[options[@"headers"] enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
[request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key];
}];
if ([options.headers() isKindOfClass:NSDictionary.class]) {
NSDictionary *headers = (NSDictionary *)options.headers();
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
[request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key];
}];
}
RCTSRWebSocket *webSocket = [[RCTSRWebSocket alloc] initWithURLRequest:request protocols:protocols];
[webSocket setDelegateDispatchQueue:[self methodQueue]];
webSocket.delegate = self;
webSocket.reactTag = socketID;
webSocket.reactTag = @(socketID);
if (!_sockets) {
_sockets = [NSMutableDictionary new];
}
_sockets[socketID] = webSocket;
_sockets[@(socketID)] = webSocket;
[webSocket open];
}
RCT_EXPORT_METHOD(send:(NSString *)message forSocketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(send:(NSString *)message forSocketID:(double)socketID)
{
[_sockets[socketID] send:message];
[_sockets[@(socketID)] send:message];
}
RCT_EXPORT_METHOD(sendBinary:(NSString *)base64String forSocketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(sendBinary:(NSString *)base64String forSocketID:(double)socketID)
{
[self sendData:[[NSData alloc] initWithBase64EncodedString:base64String options:0] forSocketID:socketID];
[self sendData:[[NSData alloc] initWithBase64EncodedString:base64String options:0] forSocketID:@(socketID)];
}
- (void)sendData:(NSData *)data forSocketID:(nonnull NSNumber *)socketID
- (void)sendData:(NSData *)data forSocketID:(NSNumber * __nonnull)socketID
{
[_sockets[socketID] send:data];
}
RCT_EXPORT_METHOD(ping:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(ping:(double)socketID)
{
[_sockets[socketID] sendPing:NULL];
[_sockets[@(socketID)] sendPing:NULL];
}
RCT_EXPORT_METHOD(close:(NSInteger)code reason:(NSString *)reason socketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(close:(double)code reason:(NSString *)reason socketID:(double)socketID)
{
[_sockets[socketID] closeWithCode:code reason:reason];
[_sockets removeObjectForKey:socketID];
[_sockets[@(socketID)] closeWithCode:code reason:reason];
[_sockets removeObjectForKey:@(socketID)];
}
- (void)setContentHandler:(id<RCTWebSocketContentHandler>)handler forSocketID:(NSString *)socketID
@ -189,6 +194,11 @@ RCT_EXPORT_METHOD(close:(NSInteger)code reason:(NSString *)reason socketID:(nonn
}];
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return std::make_shared<facebook::react::NativeWebSocketModuleSpecJSI>(self, jsInvoker);
}
@end
@implementation RCTBridge (RCTWebSocketModule)
@ -199,3 +209,7 @@ RCT_EXPORT_METHOD(close:(NSInteger)code reason:(NSString *)reason socketID:(nonn
}
@end
Class RCTWebSocketModuleCls(void) {
return RCTWebSocketModule.class;
}

Просмотреть файл

@ -26,7 +26,7 @@ public abstract class NativeWebSocketModuleSpec extends ReactContextBaseJavaModu
}
@ReactMethod
public abstract void sendBinary(String base64String, double socketID);
public abstract void sendBinary(String base64String, double forSocketID);
@ReactMethod
public abstract void removeListeners(double count);
@ -38,7 +38,7 @@ public abstract class NativeWebSocketModuleSpec extends ReactContextBaseJavaModu
public abstract void close(double code, String reason, double socketID);
@ReactMethod
public abstract void send(String message, double socketID);
public abstract void send(String message, double forSocketID);
@ReactMethod
public abstract void connect(String url, ReadableArray protocols, ReadableMap options,