How to show immersive view as background of already built iOS App ?

I have an app that is now compatible to run on Vision OS iPad Mode, I want to show an immersive view 360 Video playing as background of that app

This app was already built for iOS platform & now is compatible to run on Vision OS and I want to change background view for Vision OS platform without creating separate target for Vision OS.

Regards, Yasir Khan

Generally speaking, you'll first want to make sure that you've added Apple Vision as a supported destination in your project's General settings. It wasn't 100% clear as to whether you were building for "Apple Vision (Designed for iPad)" or "Apple Vision (visionOS)". The former is just going to run your now-visionOS compatible app in a 2D window, whereas the latter will allow you to add the necessary customizations for visionOS and create a more immersive 3D experience, which is what you'll want.

I think the answer to your question is dependent on how your app is displaying its window. Ideally, you'd want to use an ImmersiveSpace that embeds your main window, then set your 360-degree background as the background of the ImmersiveSpace. Assuming you're using the SwiftUI app lifecycle, it might help to see what your @Main entry looks like. For the sake of brevity, lets presume that your entry point is something like this, where BuildMeditationView() is the SwiftUI view you showed in your screenshot;

@main
struct MyMeditationApp: App {
   var body: some Scene {
      WindowGroup {
         BuildMeditationView()
      }
   }
}

You could modify this so that your app launches an ImmersiveSpace as its default window;

@main
struct MyMeditationApp: App {
   var body: some Scene {
      WindowGroup {
         #if os(visionOS)
         ImmersiveSpace(id: "BuildMeditationSpace") {
            ImmersiveMeditationBuilder()
        }.immersionStyle(selection: .constant(.full), in: .full)
        #else
        BuildMeditationView()
        #endif
      }
   }
}

You can learn more about the ImmersiveSpace in the developer docs, which has great detail on how to modify your app's Info.plist if you do want the app to launch an ImmersiveSpace at launch, as well as what the different immersion styles are.

You could then create a new SwiftUI view, ImmersiveMeditationBuilder, that serves as your ImmersiveSpace, and embed your original view into it. There are a few different ways to do this, one of my preferred ways is to add your original SwiftUI view as an attachment to a RealityView;

struct ImmersiveMeditationBuilder: View {
   var body: some View {
      ZStack {
         RealityView { content, attachments in

            // Set up your video background file and player
            let asset = AVURLAsset(url: Bundle.main.url(forResource: "myVideoBackgroundFile", withExtension: "mp4")!)
            let playerItem = AVPlayerItem(asset: asset)
            let player = AVPlayer()                            

            // Attach the material to a large sphere that will serve as the skybox.
            let entity = Entity()
            entity.components.set(ModelComponent(
                mesh: .generateSphere(radius: 1000),
                materials: [VideoMaterial(avPlayer: player)]
            ))

            // Ensure the texture image points inward at the viewer.
            entity.scale *= .init(x: -1, y: 1, z: 1)

            // Add the background to the main content.
            content.add(entity)

            // Add the BuildMeditationView attachment
            if let attachment = attachments.entity(for: "myMeditationBuilderView") {
               content.add(attachment)
            }

            // Play the video background
            player.replaceCurrentItem(with: playerItem)
            player.play()

         } update: content, attachments in
            // Update if necessary when the view is reloaded
         } attachments: {
            Attachment(id: "myMeditationBuilderView") {
               BuildMeditationView()
            }
         }
      }
   }
}

This assumes you want the view you showed in your screenshot to be the main view at your app's launch. If not, you could also launch your ImmersiveSpace based on some user action, which is detailed in Presenting Windows and Spaces developer article.

There are multiple ways to approach this (create an immersive space, then open a Window programmatically; create a WindowGroup scene, then open an immersive space), but you might have to experiment to find something using #if os(visionOS) to keep this all in a single target.

Regarding brandonK212's suggestion, I just want to point out an apparent typo in the code fragment. ImmersiveSpace is a kind of scene, so it should be inside the App body, not inside a WindowGroup scene. However, the general approach of using an attachment seems like a valid option here.

How to show immersive view as background of already built iOS App ?
 
 
Q