From fa201c7fb97bf06db80e19bec8925ede4625db36 Mon Sep 17 00:00:00 2001 From: vadymv-mendix <138661748+vadymv-mendix@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:30:32 +0200 Subject: [PATCH] Merge pull request #41 from mendix/MOO-2374-fix-ios-ota-loop [MOO-2374] Fix iOS OTA loop --- CHANGELOG.md | 2 ++ ios/Modules/ReactNative.swift | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4074e83..26c2ef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- We fixed an issue that could cause iOS apps to restart repeatedly after an OTA update. + ## [v0.5.0] - 2026-05-15 - We updated to React Native v0.84.1 and replaced deprecated APIs with modern equivalents. diff --git a/ios/Modules/ReactNative.swift b/ios/Modules/ReactNative.swift index caa1ab7..5f3268c 100644 --- a/ios/Modules/ReactNative.swift +++ b/ios/Modules/ReactNative.swift @@ -81,12 +81,11 @@ open class ReactNative: NSObject, RCTReloadListener { // MARK: - Reload Methods public func reload() { guard let mendixApp = mendixApp else { return } - - let otaBundleUrl = OtaJSBundleFileProvider.getBundleUrl() - if !mendixApp.isDeveloperApp, let otaBundleUrl = otaBundleUrl { - RCTReloadCommandSetBundleURL(otaBundleUrl) - } - + + // Note: under the New Architecture the bundle URL is resolved fresh in bundleURL(), + // which RCTHost re-invokes on reload. RCTReloadCommandSetBundleURL is a legacy-bridge + // mechanism that the bridgeless host ignores, so it is intentionally not used here. + if mendixApp.isDeveloperApp { let runtimeInfoUrl = AppUrl.forRuntimeInfo(mendixApp.runtimeUrl.absoluteString) RuntimeInfoProvider.getRuntimeInfo(runtimeInfoUrl) { [weak self] response in @@ -153,7 +152,19 @@ open class ReactNative: NSObject, RCTReloadListener { } public func bundleURL() -> URL? { - return bundleUrl + // New Architecture (Bridgeless): RCTHost re-invokes this provider block on every + // reload (via RCTRootViewFactory's bundleURLBlock) instead of consulting the URL set + // by RCTReloadCommandSetBundleURL. Resolve the OTA bundle fresh here so a freshly + // deployed OTA bundle is picked up after reload. Without this, every reload re-loads + // the bundle captured at host-creation time and the app loops: + // download -> deploy -> reload -> same bundle. + // + // For the developer app (and remote debugging) the cached packager URL must be used, + // so only the production path re-resolves through BundleHelper. + if mendixApp?.isDeveloperApp == true { + return bundleUrl + } + return BundleHelper.getJSBundleFile() } }