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/apps/llm/metro.config.js b/apps/llm/metro.config.js index fa6ef6d8b6..f58bbc2131 100644 --- a/apps/llm/metro.config.js +++ b/apps/llm/metro.config.js @@ -1,7 +1,4 @@ const { getDefaultConfig } = require('expo/metro-config'); -const { - wrapWithAudioAPIMetroConfig, -} = require('react-native-audio-api/metro-config'); const config = getDefaultConfig(__dirname); @@ -19,4 +16,4 @@ config.resolver = { config.resolver.assetExts.push('pte'); -module.exports = wrapWithAudioAPIMetroConfig(config); +module.exports = config; diff --git a/apps/llm/package.json b/apps/llm/package.json index e4a43406da..02aefa9935 100644 --- a/apps/llm/package.json +++ b/apps/llm/package.json @@ -26,7 +26,7 @@ "metro-config": "^0.81.5", "react": "19.1.0", "react-native": "0.81.5", - "react-native-audio-api": "^0.8.2", + "react-native-audio-api": "^0.12.2", "react-native-device-info": "^15.0.2", "react-native-executorch": "workspace:*", "react-native-executorch-expo-resource-fetcher": "workspace:*", diff --git a/apps/speech/metro.config.js b/apps/speech/metro.config.js index fa6ef6d8b6..f58bbc2131 100644 --- a/apps/speech/metro.config.js +++ b/apps/speech/metro.config.js @@ -1,7 +1,4 @@ const { getDefaultConfig } = require('expo/metro-config'); -const { - wrapWithAudioAPIMetroConfig, -} = require('react-native-audio-api/metro-config'); const config = getDefaultConfig(__dirname); @@ -19,4 +16,4 @@ config.resolver = { config.resolver.assetExts.push('pte'); -module.exports = wrapWithAudioAPIMetroConfig(config); +module.exports = config; 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 da75ab951c..146bacce98 100644 --- a/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp +++ b/packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp @@ -34,12 +34,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 0f94036f64..28be535d28 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 4094d8815d..de3b239e0c 100644 --- a/packages/react-native-executorch/react-native-executorch.podspec +++ b/packages/react-native-executorch/react-native-executorch.podspec @@ -55,6 +55,10 @@ Pod::Spec.new do |s| "common/**/*.{cpp,c,h,hpp}", ] + s.resource_bundles = { + 'RnExecutorchPrivacyInfo' => ['ios/PrivacyInfo.xcprivacy'], + } + s.libraries = "z" s.ios.vendored_frameworks = "third-party/ios/ExecutorchLib.xcframework" # Exclude file with tests to not introduce gtest dependency. diff --git a/packages/react-native-executorch/src/index.ts b/packages/react-native-executorch/src/index.ts index afd90bc780..a4d6de5b4f 100644 --- a/packages/react-native-executorch/src/index.ts +++ b/packages/react-native-executorch/src/index.ts @@ -107,6 +107,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 @@ -127,7 +129,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 ced27a0b8e..e3b334ed04 100644 --- a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts +++ b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts @@ -1,10 +1,7 @@ +import { Platform } from 'react-native'; import { ResourceSource } from '..'; import { getModelNameForUrl } from '../constants/modelUrls'; -import { - DOWNLOAD_EVENT_ENDPOINT, - LIB_VERSION, -} from '../constants/resourceFetcher'; - +import { DOWNLOAD_EVENT_ENDPOINT } from '../constants/resourceFetcher'; /** * Http status codes * @category Types @@ -213,6 +210,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) { @@ -228,18 +229,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((_) => {}); } /** diff --git a/yarn.lock b/yarn.lock index 23d84b41f6..5eab652a47 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11810,7 +11810,7 @@ __metadata: metro-config: "npm:^0.81.5" react: "npm:19.1.0" react-native: "npm:0.81.5" - react-native-audio-api: "npm:^0.8.2" + react-native-audio-api: "npm:^0.12.2" react-native-device-info: "npm:^15.0.2" react-native-executorch: "workspace:*" react-native-executorch-expo-resource-fetcher: "workspace:*" @@ -14367,15 +14367,21 @@ __metadata: languageName: node linkType: hard -"react-native-audio-api@npm:^0.8.2": - version: 0.8.4 - resolution: "react-native-audio-api@npm:0.8.4" +"react-native-audio-api@npm:^0.12.2": + version: 0.12.2 + resolution: "react-native-audio-api@npm:0.12.2" + dependencies: + semver: "npm:^7.7.3" peerDependencies: react: "*" react-native: "*" + react-native-worklets: ">= 0.6.0" + peerDependenciesMeta: + react-native-worklets: + optional: true bin: setup-rn-audio-api-web: scripts/setup-rn-audio-api-web.js - checksum: 10/35cae9ba8509c90ef625c448b5fbc40d9c8b80c3dd470f5bff9c298b2784132cec8d7370c8f2f69d1a8d586d5b91f2c4eb7b8e412bfd008729ceaf27f44550be + checksum: 10/ed495058382188c8beb51ce89f2ef14d846dc0c0a07c65a7b4c71aa106fb7ea14aa8660b05fb33941c038d1a7ab2ba4ab3eb039fe481841938c45396903c6060 languageName: node linkType: hard