diff --git a/.github/workflows/build-ios-llm-example.yml b/.github/workflows/build-ios-llm-example.yml index 4a2b2b9b99..ac1b56d694 100644 --- a/.github/workflows/build-ios-llm-example.yml +++ b/.github/workflows/build-ios-llm-example.yml @@ -58,7 +58,7 @@ jobs: -scheme llm \ -sdk iphonesimulator \ -configuration Debug \ - -destination 'platform=iOS Simulator,name=iPhone 16 Pro' \ + -destination 'platform=iOS Simulator,name=iPhone 17 Pro' \ build \ CODE_SIGNING_ALLOWED=NO \ -jobs $(sysctl -n hw.ncpu) \ diff --git a/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.cpp b/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.cpp index 1a637b15d1..af62cf5e02 100644 --- a/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.cpp +++ b/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.cpp @@ -35,7 +35,7 @@ void ETInstallerModule::registerNatives() { }); } -void ETInstallerModule::injectJSIBindings() { +void ETInstallerModule::injectJSIBindings(jni::alias_ref bundleId) { // Grab a function for fetching images via URL from Java auto fetchDataByUrl = [](std::string url) { // Attaching Current Thread to JVM @@ -67,9 +67,10 @@ void ETInstallerModule::injectJSIBindings() { }; auto _isEmulator = isEmulator(); + auto _bundleId = bundleId ? bundleId->toStdString() : std::string(); - RnExecutorchInstaller::injectJSIBindings(jsiRuntime_, jsCallInvoker_, - fetchDataByUrl, _isEmulator); + RnExecutorchInstaller::injectJSIBindings( + jsiRuntime_, jsCallInvoker_, fetchDataByUrl, _isEmulator, _bundleId); } } // namespace rnexecutorch diff --git a/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.h b/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.h index 82531ac9d5..e22eb904d0 100644 --- a/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.h +++ b/packages/react-native-executorch/android/src/main/cpp/ETInstallerModule.h @@ -24,7 +24,7 @@ class ETInstallerModule : public jni::HybridClass { static void registerNatives(); - void injectJSIBindings(); + void injectJSIBindings(jni::alias_ref bundleId); private: friend HybridBase; diff --git a/packages/react-native-executorch/android/src/main/java/com/swmansion/rnexecutorch/ETInstaller.kt b/packages/react-native-executorch/android/src/main/java/com/swmansion/rnexecutorch/ETInstaller.kt index acc43c0a9e..9648b507ff 100644 --- a/packages/react-native-executorch/android/src/main/java/com/swmansion/rnexecutorch/ETInstaller.kt +++ b/packages/react-native-executorch/android/src/main/java/com/swmansion/rnexecutorch/ETInstaller.kt @@ -45,7 +45,7 @@ class ETInstaller( callInvoker: CallInvokerHolderImpl, ): HybridData - private external fun injectJSIBindings() + private external fun injectJSIBindings(bundleId: String) init { try { @@ -60,7 +60,7 @@ class ETInstaller( @ReactMethod(isBlockingSynchronousMethod = true) override fun install(): Boolean { - injectJSIBindings() + injectJSIBindings(reactApplicationContext.packageName) return true } } diff --git a/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp b/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp index 53ee65a904..777b581719 100644 --- a/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp +++ b/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp @@ -36,12 +36,17 @@ FetchUrlFunc_t fetchUrlFunc; void RnExecutorchInstaller::injectJSIBindings( jsi::Runtime *jsiRuntime, std::shared_ptr jsCallInvoker, - FetchUrlFunc_t fetchDataFromUrl, bool isEmulator) { + FetchUrlFunc_t fetchDataFromUrl, bool isEmulator, + const std::string &bundleId) { fetchUrlFunc = fetchDataFromUrl; jsiRuntime->global().setProperty(*jsiRuntime, "__rne_isEmulator", jsi::Value(isEmulator)); + jsiRuntime->global().setProperty( + *jsiRuntime, "__rne_bundleId", + jsi::String::createFromUtf8(*jsiRuntime, bundleId)); + jsiRuntime->global().setProperty( *jsiRuntime, "loadStyleTransfer", RnExecutorchInstaller::loadModel( diff --git a/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.h b/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.h index 887a8ac0ea..0ea6292f22 100644 --- a/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.h +++ b/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.h @@ -24,7 +24,8 @@ class RnExecutorchInstaller { static void injectJSIBindings(jsi::Runtime *jsiRuntime, std::shared_ptr jsCallInvoker, - FetchUrlFunc_t fetchDataFromUrl, bool isEmulator); + FetchUrlFunc_t fetchDataFromUrl, bool isEmulator, + const std::string &bundleId); private: template diff --git a/packages/react-native-executorch/ios/RnExecutorch/ETInstaller.mm b/packages/react-native-executorch/ios/RnExecutorch/ETInstaller.mm index 2a8bc519ba..e454689365 100644 --- a/packages/react-native-executorch/ios/RnExecutorch/ETInstaller.mm +++ b/packages/react-native-executorch/ios/RnExecutorch/ETInstaller.mm @@ -43,8 +43,10 @@ @implementation ETInstaller } }; bool isEmulator = TARGET_OS_SIMULATOR; + NSString *nsBundleId = [[NSBundle mainBundle] bundleIdentifier]; + std::string bundleId = nsBundleId ? nsBundleId.UTF8String : ""; rnexecutorch::RnExecutorchInstaller::injectJSIBindings( - jsiRuntime, jsCallInvoker, fetchUrl, isEmulator); + jsiRuntime, jsCallInvoker, fetchUrl, isEmulator, bundleId); NSLog(@"Successfully installed JSI bindings for react-native-executorch!"); return @true; diff --git a/packages/react-native-executorch/react-native-executorch.podspec b/packages/react-native-executorch/react-native-executorch.podspec index daf0da27c7..0bd1168c8a 100644 --- a/packages/react-native-executorch/react-native-executorch.podspec +++ b/packages/react-native-executorch/react-native-executorch.podspec @@ -60,6 +60,10 @@ Pod::Spec.new do |s| "third-party/common/phonemis/src/**/*.{cpp,hpp,h}", ] + s.resource_bundles = { + 'RnExecutorchPrivacyInfo' => ['ios/PrivacyInfo.xcprivacy'], + } + s.libraries = "z" s.ios.vendored_frameworks = "third-party/ios/ExecutorchLib.xcframework" diff --git a/packages/react-native-executorch/src/index.ts b/packages/react-native-executorch/src/index.ts index 1f190d41f5..b371f18ab6 100644 --- a/packages/react-native-executorch/src/index.ts +++ b/packages/react-native-executorch/src/index.ts @@ -120,6 +120,8 @@ declare global { ) => Promise; // eslint-disable-next-line camelcase var __rne_isEmulator: boolean; + // eslint-disable-next-line camelcase + var __rne_bundleId: string; } // eslint-disable no-var @@ -142,7 +144,8 @@ if ( global.loadTextToSpeechKokoro == null || global.loadOCR == null || global.loadVerticalOCR == null || - global.__rne_isEmulator == null + global.__rne_isEmulator == null || + global.__rne_bundleId == null ) { if (!ETInstallerNativeModule) { throw new Error( diff --git a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts index 46f4b34e2d..4ad98e3a83 100644 --- a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts +++ b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts @@ -1,8 +1,6 @@ import { getModelNameForUrl } from '../constants/modelUrls'; -import { - DOWNLOAD_EVENT_ENDPOINT, - LIB_VERSION, -} from '../constants/resourceFetcher'; +import { DOWNLOAD_EVENT_ENDPOINT } from '../constants/resourceFetcher'; +import { Platform } from 'react-native'; /** * Http status codes * @category Types @@ -174,6 +172,10 @@ export namespace ResourceFetcherUtils { return global.__rne_isEmulator; } + export function getBundleId(): string { + return global.__rne_bundleId; + } + function getModelNameFromUri(uri: string): string { const knownName = getModelNameForUrl(uri); if (knownName) { @@ -189,18 +191,18 @@ export namespace ResourceFetcherUtils { * @param uri - The URI of the downloaded resource. */ export function triggerDownloadEvent(uri: string) { - try { - fetch(DOWNLOAD_EVENT_ENDPOINT, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - modelName: getModelNameFromUri(uri), - countryCode: getCountryCode(), - isEmulator: isEmulator(), - libVersion: LIB_VERSION, - }), - }); - } catch (e) {} + fetch(DOWNLOAD_EVENT_ENDPOINT, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + bundleId: getBundleId(), + countryCode: getCountryCode(), + isEmulator: isEmulator(), + libVersion: require('../../package.json').version, + modelName: getModelNameFromUri(uri), + system: Platform.OS, + }), + }).catch((_) => {}); } /**