mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add ObjC Turbo Module Event Emitter example (#44914)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44914 Shows a proof of concept how '*strongly typed Turbo Module scoped*' `EventEmitters` can be used in a ObjC Turbo Module. ## Changelog: [iOS] [Added] - Add ObjC Turbo Module Event Emitter example Reviewed By: rshest Differential Revision: D57650830 fbshipit-source-id: c5c2dee4766484e9e58415e33c084999a9ae3bc6
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8b121c5071
commit
f473a2f8f4
+22
-2
@@ -7,8 +7,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <memory>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
@@ -16,6 +14,9 @@
|
||||
#import <React/RCTModuleMethod.h>
|
||||
#import <ReactCommon/CallInvoker.h>
|
||||
#import <ReactCommon/TurboModule.h>
|
||||
#import <react/bridging/bridging.h>
|
||||
#import <functional>
|
||||
#import <memory>
|
||||
#import <string>
|
||||
#import <unordered_map>
|
||||
|
||||
@@ -27,12 +28,21 @@ namespace facebook::react {
|
||||
|
||||
class CallbackWrapper;
|
||||
class Instance;
|
||||
using EventEmitterCallback = std::function<void(const std::string &, id)>;
|
||||
|
||||
namespace TurboModuleConvertUtils {
|
||||
jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value);
|
||||
id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, std::shared_ptr<CallInvoker> jsInvoker);
|
||||
} // namespace TurboModuleConvertUtils
|
||||
|
||||
template <>
|
||||
struct Bridging<id> {
|
||||
static jsi::Value toJs(jsi::Runtime &rt, const id &value)
|
||||
{
|
||||
return TurboModuleConvertUtils::convertObjCObjectToJSIValue(rt, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ObjC++ specific TurboModule base class.
|
||||
*/
|
||||
@@ -64,6 +74,8 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
||||
protected:
|
||||
void setMethodArgConversionSelector(NSString *methodName, size_t argIndex, NSString *fnName);
|
||||
|
||||
void setEventEmitterCallback(EventEmitterCallback eventEmitterCallback);
|
||||
|
||||
/**
|
||||
* Why is this virtual?
|
||||
*
|
||||
@@ -154,9 +166,17 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@interface EventEmitterCallbackWrapper : NSObject {
|
||||
@public
|
||||
facebook::react::EventEmitterCallback _eventEmitterCallback;
|
||||
}
|
||||
@end
|
||||
|
||||
@protocol RCTTurboModule <NSObject>
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params;
|
||||
@optional
|
||||
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
|
||||
@end
|
||||
|
||||
/**
|
||||
|
||||
+13
@@ -813,5 +813,18 @@ void ObjCTurboModule::setMethodArgConversionSelector(NSString *methodName, size_
|
||||
methodArgConversionSelectors_[methodName][argIndex] = selectorValue;
|
||||
}
|
||||
|
||||
void ObjCTurboModule::setEventEmitterCallback(EventEmitterCallback eventEmitterCallback)
|
||||
{
|
||||
if ([instance_ conformsToProtocol:@protocol(RCTTurboModule)] &&
|
||||
[instance_ respondsToSelector:@selector(setEventEmitterCallback:)]) {
|
||||
EventEmitterCallbackWrapper *wrapper = [EventEmitterCallbackWrapper new];
|
||||
wrapper->_eventEmitterCallback = std::move(eventEmitterCallback);
|
||||
[(id<RCTTurboModule>)instance_ setEventEmitterCallback:wrapper];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
@implementation EventEmitterCallbackWrapper
|
||||
@end
|
||||
|
||||
+9
-1
@@ -43,7 +43,15 @@
|
||||
|
||||
@end
|
||||
|
||||
@interface NativeSampleTurboModuleSpecBase : NSObject
|
||||
@interface NativeSampleTurboModuleSpecBase : NSObject {
|
||||
@protected
|
||||
facebook::react::EventEmitterCallback _eventEmitterCallback;
|
||||
}
|
||||
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *_Nonnull)eventEmitterCallbackWrapper;
|
||||
- (void)emitOnPress;
|
||||
- (void)emitOnClick:(NSString *)value;
|
||||
- (void)emitOnChange:(NSDictionary *)value;
|
||||
- (void)emitOnSubmit:(NSArray *)value;
|
||||
@end
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
+31
@@ -224,9 +224,40 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboMo
|
||||
methodMap_["getObjectAssert"] = MethodMetadata{1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObjectAssert};
|
||||
methodMap_["promiseAssert"] = MethodMetadata{0, __hostFunction_NativeSampleTurboModuleSpecJSI_promiseAssert};
|
||||
methodMap_["getConstants"] = MethodMetadata{0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants};
|
||||
eventEmitterMap_["onPress"] = std::make_shared<AsyncEventEmitter<id>>();
|
||||
eventEmitterMap_["onClick"] = std::make_shared<AsyncEventEmitter<id>>();
|
||||
eventEmitterMap_["onChange"] = std::make_shared<AsyncEventEmitter<id>>();
|
||||
eventEmitterMap_["onSubmit"] = std::make_shared<AsyncEventEmitter<id>>();
|
||||
setEventEmitterCallback([&](const std::string &name, id value) {
|
||||
static_cast<AsyncEventEmitter<id> &>(*eventEmitterMap_[name]).emit(value);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@implementation NativeSampleTurboModuleSpecBase
|
||||
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *_Nonnull)eventEmitterCallbackWrapper
|
||||
{
|
||||
_eventEmitterCallback = std::move(eventEmitterCallbackWrapper->_eventEmitterCallback);
|
||||
}
|
||||
|
||||
- (void)emitOnPress
|
||||
{
|
||||
_eventEmitterCallback("onPress", nil);
|
||||
}
|
||||
|
||||
- (void)emitOnClick:(NSString *)value
|
||||
{
|
||||
_eventEmitterCallback("onClick", value);
|
||||
}
|
||||
|
||||
- (void)emitOnChange:(NSDictionary *)value
|
||||
{
|
||||
_eventEmitterCallback("onChange", value);
|
||||
}
|
||||
|
||||
- (void)emitOnSubmit:(NSArray *)value
|
||||
{
|
||||
_eventEmitterCallback("onSubmit", value);
|
||||
}
|
||||
@end
|
||||
|
||||
+4
@@ -82,6 +82,10 @@ RCT_EXPORT_MODULE()
|
||||
RCT_EXPORT_METHOD(voidFunc)
|
||||
{
|
||||
// Nothing to do
|
||||
[self emitOnPress];
|
||||
[self emitOnClick:@"click"];
|
||||
[self emitOnChange:@{@"a" : @1, @"b" : @"two"}];
|
||||
[self emitOnSubmit:@[ @{@"a" : @1, @"b" : @"two"}, @{@"a" : @3, @"b" : @"four"} ]];
|
||||
}
|
||||
|
||||
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getBool : (BOOL)arg)
|
||||
|
||||
Reference in New Issue
Block a user