import AVKit import OSLog import SwiftUI import RealityKit import RealityKitContent struct InitialImmersiveView: View { let logger = Logger(subsystem: SUBSYSTEM, category: "InitialImmersiveView") @Environment(\.scenePhase) var scenePhase @Environment(AppModel.self) var appModel private let rootEntity = Entity() var body: some View { RealityView { content, attachments in logger.info("\(#function) \(#line) `content, attachments in`") updateScene(content: content, attachments: attachments) } update: { content, attachments in logger.info("\(#function) \(#line) `update: { content, attachments in`") updateScene(content: content, attachments: attachments) } placeholder: { let _ = logger.info("\(#function) \(#line) `placeholder`") ProgressView() } attachments: { let _ = logger.info("\(#function) \(#line) `attachments`") Attachment(id: "OpenSkysphereView") { Button { appModel.showingScene = .threeSixtySkyShpere } label: { Text("Open Skysphere") } } } .onChange(of: scenePhase, { oldValue, newValue in logger.info("\(#function) \(#line) `onChange(of: scenePhase` scenePhase oldValue \(String(describing: oldValue)) scenePhase newValue \(String(describing: newValue))") switch newValue { case .active: logger.info("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") case .background: logger.info("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") unloadScenes() case .inactive: logger.info("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") @unknown default: logger.warning("\(#function) \(#line) scenePhase newValue \(String(describing: newValue))") } }) } func updateScene(content: RealityViewContent, attachments: RealityViewAttachments) { logger.info("\(#function) \(#line)") guard scenePhase == .active else { logger.info("\(#function) \(#line) escaping since app backgrounded") return } if rootEntity.children.isEmpty { Task{ await loadScenes(content: content, attachments: attachments) } } } func loadScenes(content: RealityViewContent, attachments: RealityViewAttachments) async { logger.info("\(#function) \(#line)") guard let openSkysphereViewButton = attachments.entity(for: "OpenSkysphereView") else { logger.error("\(#function) \(#line) missing attachment") assertionFailure("missing attachment") return } openSkysphereViewButton.position = [0.0, 0.1, -2.5] openSkysphereViewButton.scale = scaleForAttachements rootEntity.addChild(openSkysphereViewButton) content.add(rootEntity) } func unloadScenes() { logger.info("\(#function) \(#line)") rootEntity.children.removeAll() } }