From 6789fc532be22ba0789424ba50b4917a33e8e020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kopci=C5=84ski?= Date: Wed, 15 Jul 2026 11:16:57 +0200 Subject: [PATCH 1/3] feat: added system and bundleId to telemetry --- .../src/utils/ResourceFetcherUtils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts index 46f4b34e2d..239a897a83 100644 --- a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts +++ b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts @@ -3,6 +3,8 @@ import { DOWNLOAD_EVENT_ENDPOINT, LIB_VERSION, } from '../constants/resourceFetcher'; +import DeviceInfo from 'react-native-device-info'; +import { Platform } from 'react-native'; /** * Http status codes * @category Types @@ -194,10 +196,12 @@ export namespace ResourceFetcherUtils { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - modelName: getModelNameFromUri(uri), + bundleId: DeviceInfo.getBundleId(), countryCode: getCountryCode(), isEmulator: isEmulator(), - libVersion: LIB_VERSION, + libVersion: require('../../package.json').version, + modelName: getModelNameFromUri(uri), + system: Platform.OS, }), }); } catch (e) {} From 6c530e03062a57586888025f1a086bedc3e62e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kopci=C5=84ski?= Date: Fri, 17 Jul 2026 12:13:32 +0200 Subject: [PATCH 2/3] gh action fix --- .github/workflows/build-ios-llm-example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) \ From 473bf811b3a67726f7b7347e8dc649594c826284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kopci=C5=84ski?= Date: Tue, 21 Jul 2026 15:58:41 +0200 Subject: [PATCH 3/3] changed bundleId from react-native-device-info to native code implementation, review fix --- .../src/main/cpp/ETInstallerModule.cpp | 7 ++-- .../android/src/main/cpp/ETInstallerModule.h | 2 +- .../com/swmansion/rnexecutorch/ETInstaller.kt | 4 +-- .../rnexecutorch/RnExecutorchInstaller.cpp | 7 +++- .../rnexecutorch/RnExecutorchInstaller.h | 3 +- .../ios/RnExecutorch/ETInstaller.mm | 4 ++- .../react-native-executorch.podspec | 4 +++ packages/react-native-executorch/src/index.ts | 5 ++- .../src/utils/ResourceFetcherUtils.ts | 36 +++++++++---------- 9 files changed, 43 insertions(+), 29 deletions(-) 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 239a897a83..4ad98e3a83 100644 --- a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts +++ b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts @@ -1,9 +1,5 @@ import { getModelNameForUrl } from '../constants/modelUrls'; -import { - DOWNLOAD_EVENT_ENDPOINT, - LIB_VERSION, -} from '../constants/resourceFetcher'; -import DeviceInfo from 'react-native-device-info'; +import { DOWNLOAD_EVENT_ENDPOINT } from '../constants/resourceFetcher'; import { Platform } from 'react-native'; /** * Http status codes @@ -176,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) { @@ -191,20 +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({ - bundleId: DeviceInfo.getBundleId(), - countryCode: getCountryCode(), - isEmulator: isEmulator(), - libVersion: require('../../package.json').version, - modelName: getModelNameFromUri(uri), - system: Platform.OS, - }), - }); - } 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((_) => {}); } /**