From b7bda8d3d8ec085ba50a7f34436d504911bd9a96 Mon Sep 17 00:00:00 2001 From: Hubert Gancarczyk Date: Wed, 10 Jul 2024 07:32:49 +0200 Subject: [PATCH] chore: setup ios with jsi --- cpp/JSIExampleHostObject.cpp | 30 +++++++++------ cpp/JSIExampleHostObject.h | 2 +- .../project.pbxproj | 10 ++++- example/ios/Podfile | 2 - example/ios/Podfile.lock | 8 ++-- example/src/App.tsx | 9 +++-- ios/AudioContext.h | 15 -------- ios/AudioContext.mm | 21 ---------- ios/JSIExampleModule.h | 5 +++ ios/JSIExampleModule.mm | 38 +++++++++++++++++++ package.json | 2 +- src/JSIExample.ts | 2 +- 12 files changed, 82 insertions(+), 62 deletions(-) delete mode 100644 ios/AudioContext.h delete mode 100644 ios/AudioContext.mm create mode 100644 ios/JSIExampleModule.h create mode 100644 ios/JSIExampleModule.mm diff --git a/cpp/JSIExampleHostObject.cpp b/cpp/JSIExampleHostObject.cpp index 1f28c9e6..75c00889 100644 --- a/cpp/JSIExampleHostObject.cpp +++ b/cpp/JSIExampleHostObject.cpp @@ -11,17 +11,17 @@ namespace example { return propertyNames; } - jsi::Value JSIExampleHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &propNameId) - { + jsi::Value JSIExampleHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &propNameId) { auto propName = propNameId.utf8(runtime); - if (propName == "helloWorld") - { - return jsi::Function::createFromHostFunction(runtime, propNameId, 0, - [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) - { - return this->helloWorld(rt); - }); + if (propName == "helloWorld") { + return jsi::Function::createFromHostFunction(runtime, propNameId, 2, + [this](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *args, size_t count) { + if (count != 2) { + throw std::invalid_argument("helloWorld expects exactly two arguments"); + } + return this->helloWorld(rt, args[0], args[1]); + }); } throw std::runtime_error("Not yet implemented!"); @@ -38,8 +38,14 @@ namespace example { throw std::runtime_error("Not yet implemented!"); } - jsi::Value JSIExampleHostObject::helloWorld(jsi::Runtime &runtime) - { - return jsi::String::createFromUtf8(runtime, "Hello World using jsi::HostObject!"); + jsi::Value JSIExampleHostObject::helloWorld(jsi::Runtime &runtime, const jsi::Value &value, const jsi::Value &value2) { + if (value.isNumber() && value2.isNumber()) { + // Extract numbers and add them + double result = value.asNumber() + value2.asNumber(); + return jsi::Value(result); + } else { + // Handle other cases (e.g., one is a number and the other is a string) + return jsi::Value::undefined(); + } } } diff --git a/cpp/JSIExampleHostObject.h b/cpp/JSIExampleHostObject.h index 3ec12423..e305e3a8 100644 --- a/cpp/JSIExampleHostObject.h +++ b/cpp/JSIExampleHostObject.h @@ -17,7 +17,7 @@ namespace example jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override; void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override; std::vector getPropertyNames(jsi::Runtime &rt) override; - static jsi::Value helloWorld(jsi::Runtime &); + static jsi::Value helloWorld(jsi::Runtime &, const jsi::Value &value, const jsi::Value &value2); }; } // namespace margelo diff --git a/example/ios/AudioContextExample.xcodeproj/project.pbxproj b/example/ios/AudioContextExample.xcodeproj/project.pbxproj index ed428ae8..f35d8b5c 100644 --- a/example/ios/AudioContextExample.xcodeproj/project.pbxproj +++ b/example/ios/AudioContextExample.xcodeproj/project.pbxproj @@ -592,7 +592,10 @@ "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; @@ -664,7 +667,10 @@ "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; diff --git a/example/ios/Podfile b/example/ios/Podfile index 5dd276ef..bbce5e3e 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,3 @@ -ENV['RCT_NEW_ARCH_ENABLED'] = '1' - # Resolve react_native_pods.rb with node to allow for hoisting require Pod::Executable.execute_command('node', ['-p', 'require.resolve( diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index b3eff311..841860c1 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1395,15 +1395,15 @@ SPEC CHECKSUMS: React-jsitracing: 6b3c8c98313642140530f93c46f5a6ca4530b446 React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304 React-Mapbuffer: 9f68550e7c6839d01411ac8896aea5c868eff63a - react-native-audio-context: 11ae1a36b7d91d7cbd04cf5d5e27a6a9fb145eb8 + react-native-audio-context: 4184c3164b1911b9a2632be8dfeecc0cb3d41c9b React-nativeconfig: fa5de9d8f4dbd5917358f8ad3ad1e08762f01dcb React-NativeModulesApple: 585d1b78e0597de364d259cb56007052d0bda5e5 React-perflogger: 7bb9ba49435ff66b666e7966ee10082508a203e8 React-RCTActionSheet: a2816ae2b5c8523c2bc18a8f874a724a096e6d97 React-RCTAnimation: e78f52d7422bac13e1213e25e9bcbf99be872e1a - React-RCTAppDelegate: 4843f73d1089552a7d7f4ec6d29e9942c8f5e161 + React-RCTAppDelegate: 24f46de486cfa3a9f46e4b0786eaf17d92e1e0c6 React-RCTBlob: 9f9d6599d1b00690704dadc4a4bc33a7e76938be - React-RCTFabric: 56eb7973b13cd9d7be03ca06f621ed0edd124b81 + React-RCTFabric: 609e66bb0371b9082c62ed677ee0614efe711bf2 React-RCTImage: 39dd5aee6b92213845e1e7a7c41865801dc33493 React-RCTLinking: 35d742a982f901f9ea416d772763e2da65c2dc7d React-RCTNetwork: b078576c0c896c71905f841716b9f9f5922111dc @@ -1422,6 +1422,6 @@ SPEC CHECKSUMS: SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 88480008ccacea6301ff7bf58726e27a72931c8d -PODFILE CHECKSUM: 1b2da41d5518b36ddce0d4e029682759a82955cc +PODFILE CHECKSUM: 122f19e943aa833c1ad02dd5fd0e0364e65fe9ce COCOAPODS: 1.14.3 diff --git a/example/src/App.tsx b/example/src/App.tsx index 4234e373..c4e096b2 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,10 +1,11 @@ +import React from 'react'; import { StyleSheet, View, Text } from 'react-native'; import { JSIExample } from '../../src/JSIExample'; -export default function App() { +const App: React.FC = () => { const sayHello = () => { //JSIExample.helloWorld = 'Hello World'; - return JSIExample.helloWorld(); + return JSIExample.helloWorld(2, 3); }; return ( @@ -12,7 +13,9 @@ export default function App() { {sayHello()} ); -} +}; + +export default App; const styles = StyleSheet.create({ container: { diff --git a/ios/AudioContext.h b/ios/AudioContext.h deleted file mode 100644 index de2a3b10..00000000 --- a/ios/AudioContext.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef __cplusplus -#import "react-native-audio-context.h" -#endif - -#ifdef RCT_NEW_ARCH_ENABLED -#import "RNAudioContextSpec.h" - -@interface AudioContext : NSObject -#else -#import - -@interface AudioContext : NSObject -#endif - -@end diff --git a/ios/AudioContext.mm b/ios/AudioContext.mm deleted file mode 100644 index dca8c82e..00000000 --- a/ios/AudioContext.mm +++ /dev/null @@ -1,21 +0,0 @@ -#import "AudioContext.h" - -@implementation AudioContext -RCT_EXPORT_MODULE() - -// Don't compile this code when we build for the old architecture. -#ifdef RCT_NEW_ARCH_ENABLED -- (NSNumber *)multiply:(double)a b:(double)b { - NSNumber *result = @(audiocontext::multiply(a, b)); - - return result; -} - -- (std::shared_ptr)getTurboModule: - (const facebook::react::ObjCTurboModule::InitParams &)params -{ - return std::make_shared(params); -} -#endif - -@end diff --git a/ios/JSIExampleModule.h b/ios/JSIExampleModule.h new file mode 100644 index 00000000..bcf1dd02 --- /dev/null +++ b/ios/JSIExampleModule.h @@ -0,0 +1,5 @@ +#import + +@interface JSIExampleModule : NSObject + +@end diff --git a/ios/JSIExampleModule.mm b/ios/JSIExampleModule.mm new file mode 100644 index 00000000..0e3fb779 --- /dev/null +++ b/ios/JSIExampleModule.mm @@ -0,0 +1,38 @@ +#import "JSIExampleModule.h" + +#import +#import +#import + +#import "../cpp/JSIExampleHostObject.h" + +@implementation JSIExampleModule + +RCT_EXPORT_MODULE(JSIExample) + +RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) +{ + NSLog(@"Installing JSI bindings for react-native-audio-context..."); + RCTBridge* bridge = [RCTBridge currentBridge]; + RCTCxxBridge* cxxBridge = (RCTCxxBridge*)bridge; + if (cxxBridge == nil) { + return @false; + } + + using namespace facebook; + + auto jsiRuntime = (jsi::Runtime*) cxxBridge.runtime; + if (jsiRuntime == nil) { + return @false; + } + auto& runtime = *jsiRuntime; + + auto hostObject = std::make_shared(); + auto object = jsi::Object::createFromHostObject(runtime, hostObject); + runtime.global().setProperty(runtime, "__JSIExampleProxy", std::move(object)); + + NSLog(@"Successfully installed JSI bindings for react-native-audio-context!"); + return @true; +} + +@end diff --git a/package.json b/package.json index 32814572..2b2771ac 100644 --- a/package.json +++ b/package.json @@ -164,7 +164,7 @@ "jsSrcsDir": "src" }, "create-react-native-library": { - "type": "module-new", + "type": "module-legacy", "languages": "cpp", "version": "0.37.1" } diff --git a/src/JSIExample.ts b/src/JSIExample.ts index 1dc61477..ddd6070b 100644 --- a/src/JSIExample.ts +++ b/src/JSIExample.ts @@ -1,7 +1,7 @@ import { NativeModules, Platform } from 'react-native'; export interface JSIExampleWrapper { - helloWorld(): string; + helloWorld(num1: number, num2: number): string; } // global func declaration for JSI functions