From abbd1d994316cd3197dc40ed801f1967874283dd Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 18 Nov 2024 19:38:23 -0800 Subject: [PATCH] fix(visionos): multi-scene improvements --- .../ios/src/NativeScriptMainWindow.swift | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/core/platforms/ios/src/NativeScriptMainWindow.swift b/packages/core/platforms/ios/src/NativeScriptMainWindow.swift index a09fe9fd83..f5ea21a104 100644 --- a/packages/core/platforms/ios/src/NativeScriptMainWindow.swift +++ b/packages/core/platforms/ios/src/NativeScriptMainWindow.swift @@ -2,6 +2,14 @@ import SwiftUI import NativeScriptEmbedder import UIKit +// Ensure runtime phases are called only once per app lifecycle +// In multi-scene apps, we need to ensure runtime doesn't reinit alongside main window +// For example, if @State is used to drive @Environment at the root level, we need to ensure +// a rerender of the main body doesn't cause runtime to cycle again +var hasMainInit = false +var hasMainBoot = false +var hasMainSetMainScene = false + @available(iOS 14.0, *) struct NativeScriptMainWindow: Scene { @@ -18,12 +26,18 @@ struct NativeScriptMainWindow: Scene { // windowStyle is only supported on visionOS WindowGroup { NativeScriptAppView(found: { windowScene in - NativeScriptEmbedder.sharedInstance().setWindowScene(windowScene) + if (!hasMainSetMainScene) { + hasMainSetMainScene = true + NativeScriptEmbedder.sharedInstance().setWindowScene(windowScene) + } }).onAppear { // print("NativeScriptAppView onAppear") - DispatchQueue.main.async { - NativeScriptEmbedder.boot() - } + if (!hasMainBoot) { + hasMainBoot = true + DispatchQueue.main.async { + NativeScriptEmbedder.boot() + } + } }.onReceive(NotificationCenter.default .publisher(for: NSNotification.Name("NativeScriptWindowOpen")), perform: { obj in let info = parseWindowInfo(obj: obj) @@ -68,9 +82,12 @@ struct NativeScriptMainWindow: Scene { } init() { - NativeScriptViewFactory.initShared() - NativeScriptEmbedder.sharedInstance().setDelegate(NativeScriptViewFactory.shared) - NativeScriptEmbedder.setup() + if (!hasMainInit) { + hasMainInit = true + NativeScriptViewFactory.initShared() + NativeScriptEmbedder.sharedInstance().setDelegate(NativeScriptViewFactory.shared) + NativeScriptEmbedder.setup() + } } #if os(visionOS)