Skip to content

Commit

Permalink
4. Call Swift/Kotlin from TurboModule
Browse files Browse the repository at this point in the history
  • Loading branch information
barthap committed May 19, 2021
1 parent 5244ab8 commit ed4adec
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 9 deletions.
19 changes: 18 additions & 1 deletion android/cpp-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <fbjni/fbjni.h>
#include <jsi/jsi.h>

#include "PlatformAdapter.h"
#include "TurboUtilsModule.h"
#include "Logging.h"

Expand All @@ -27,6 +28,20 @@ struct JGreetingManager : jni::JavaClass<JGreetingManager> {
}
};

// Delegation of platform-specific code from JSI TurboModule
class AndroidAdapter : public turboutils::PlatformAdapter {
jni::global_ref<JGreetingManager> _greetingManager;
public:
AndroidAdapter() {
auto recognizer = JGreetingManager::create("JNI");
_greetingManager = jni::make_global(recognizer);
}

std::string delegateGreeting(const std::string &name) override {
return _greetingManager->prepareGreeting(name);
}
};

// this reflects com.myturboutils.NativeProxy class
struct NativeProxy : jni::JavaClass<NativeProxy> {
static constexpr auto kJavaDescriptor = "Lcom/myturboutils/NativeProxy;";
Expand All @@ -47,14 +62,16 @@ struct NativeProxy : jni::JavaClass<NativeProxy> {
static void installNativeJsi(jni::alias_ref<jni::JObject> thiz,
jlong jsiRuntimePtr,
jni::alias_ref<react::CallInvokerHolder::javaobject> jsCallInvokerHolder) {

auto jsiRuntime = reinterpret_cast<jsi::Runtime*>(jsiRuntimePtr);
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
auto platformAdapter = std::make_unique<AndroidAdapter>();

// initialize jsi module
turboutils::installJsi(*jsiRuntime);

// initialize turbo module
turboutils::installTurboModule(*jsiRuntime, jsCallInvoker);
turboutils::installTurboModule(*jsiRuntime, jsCallInvoker, std::move(platformAdapter));
}

private:
Expand Down
25 changes: 25 additions & 0 deletions cpp/PlatformAdapter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// PlatformAdapter.h
// my-turbo-utils
//
// Created by Bartłomiej Klocek on 19/05/2021.
//

#ifndef PlatformAdapter_h
#define PlatformAdapter_h

#include <string>

namespace turboutils {


class PlatformAdapter {
public:
virtual ~PlatformAdapter() = default;

virtual std::string delegateGreeting(const std::string &name) = 0;
};

}

#endif /* PlatformAdapter_h */
11 changes: 7 additions & 4 deletions cpp/TurboUtilsModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ namespace turboutils
}

/*** TurboModule implementation ***/
void installTurboModule(jsi::Runtime& runtime, std::shared_ptr<react::CallInvoker> jsCallInvoker) {
void installTurboModule(jsi::Runtime& runtime,
std::shared_ptr<react::CallInvoker> jsCallInvoker,
std::unique_ptr<PlatformAdapter> platformAdapter) {

std::shared_ptr<UtilsTurboModule> nativeModule =
std::make_shared<UtilsTurboModule>(jsCallInvoker);
std::make_shared<UtilsTurboModule>(jsCallInvoker, std::move(platformAdapter));

// register UtilsTurboModule instance as global._myUtilsTurboModule
runtime.global().setProperty(
Expand Down Expand Up @@ -58,8 +61,8 @@ namespace turboutils
/**************************************************************************/

jsi::String UtilsTurboModule::nativeGreeting(jsi::Runtime &rt, const jsi::String &name) {
auto msg = std::string("Greeting not implemented yet for ") + name.utf8(rt);
return jsi::String::createFromAscii(rt, msg);
auto result = this->_platformAdapter->delegateGreeting(name.utf8(rt));
return jsi::String::createFromAscii(rt, result);
}

jsi::Value UtilsTurboModule::nativeSumSquares(jsi::Runtime &rt, double a, double b) {
Expand Down
12 changes: 9 additions & 3 deletions cpp/TurboUtilsModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <ReactCommon/TurboModule.h>
#endif

#include "PlatformAdapter.h"

namespace turboutils {
using namespace facebook;

Expand All @@ -17,7 +19,9 @@ namespace turboutils {
void installJsi(jsi::Runtime& rt);

/****** TURBO MODULE STUFF BELOW *******/
void installTurboModule(jsi::Runtime& runtime, std::shared_ptr<react::CallInvoker> jsCallInvoker);
void installTurboModule(jsi::Runtime& runtime,
std::shared_ptr<react::CallInvoker> jsCallInvoker,
std::unique_ptr<PlatformAdapter> platformAdapter);

// This abstract class defines JSI interfaces for the turbo module
class JSI_EXPORT TurboUtilsSpecJSI : public facebook::react::TurboModule {
Expand All @@ -33,9 +37,11 @@ namespace turboutils {

// This is the actual implementation of the module methods
class UtilsTurboModule : public TurboUtilsSpecJSI {
std::unique_ptr<PlatformAdapter> _platformAdapter;
public:
UtilsTurboModule(std::shared_ptr<react::CallInvoker> jsInvoker)
: TurboUtilsSpecJSI(jsInvoker) {}
UtilsTurboModule(std::shared_ptr<react::CallInvoker> jsInvoker,
std::unique_ptr<PlatformAdapter> platformAdapter)
: TurboUtilsSpecJSI(jsInvoker), _platformAdapter(std::move(platformAdapter)) {}

jsi::String nativeGreeting(jsi::Runtime &rt, const jsi::String &name) override;
jsi::Value nativeSumSquares(jsi::Runtime &rt, double a, double b) override;
Expand Down
36 changes: 36 additions & 0 deletions ios/IosTurboUtilsAdapter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// IosTurboUtilsAdapter.h
// my-turbo-utils
//
// Created by Bartłomiej Klocek on 19/05/2021.
//

#ifndef IosTurboUtilsAdapter_h
#define IosTurboUtilsAdapter_h

#include "PlatformAdapter.h"
#import "my_turbo_utils-Swift.h"

class IosAdapter : public turboutils::PlatformAdapter {
GreetingManager* _greetingManager;
public:
IosAdapter() {
_greetingManager = [[GreetingManager alloc] initWithTag:@"iOS"];
}
virtual ~IosAdapter() {
_greetingManager = nil;
}

std::string delegateGreeting(const std::string &name) override {
// convert std::string to NSString*
NSString* nsName = [[NSString alloc] initWithCString:name.c_str() encoding:NSUTF8StringEncoding];

// call Swift method
NSString* result = [_greetingManager makeGreetingForName:nsName];

// convert back to std::string
return std::string([result UTF8String]);
}
};

#endif /* IosTurboUtilsAdapter_h */
4 changes: 3 additions & 1 deletion ios/MyTurboUtils.mm
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "MyTurboUtils.h"
#import "IosTurboUtilsAdapter.h"
#import "my_turbo_utils-Swift.h"

#include "TurboUtilsModule.h"
Expand Down Expand Up @@ -34,12 +35,13 @@ - (void)setBridge:(RCTBridge *)bridge {

jsi::Runtime* jsiRuntime = (jsi::Runtime *)cxxBridge.runtime;
auto callInvoker = bridge.jsCallInvoker;
auto platformAdapter = std::make_unique<IosAdapter>();

// init jsi-based module
turboutils::installJsi(*jsiRuntime);

// init turbo module
turboutils::installTurboModule(*jsiRuntime, callInvoker);
turboutils::installTurboModule(*jsiRuntime, callInvoker, std::move(platformAdapter));
}


Expand Down

0 comments on commit ed4adec

Please sign in to comment.