Swiftui - SKStoreProductViewController inside .sheet action open 2 views - why?

Hi,

In my app, a button should be pressed and then the App Store product page of a specific app should be displayed within the application. My solution creates a UIViewControllerView of the Apple product page with .sheet.

Unfortunately, an empty view appears first and a little later the App Store product page is displayed too and the empty view is in the background. If you then close the App Store page, you also have to close the empty view until you are back in the ContentView.

Here are a screenshot.

How can I prevent the blank page or what do I have to adjust in my code so that the page does not appear?

Here is my code.

import SwiftUI

struct ContentView: View {
    
    @State private var showAppStore = false
    
    var body: some View {
    
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
                .onTapGesture {
                    self.showAppStore.toggle()
                }
                .sheet(isPresented: $showAppStore) {
                    AppStoreProductView()
                }
            Text("Hello, world!")
        }
        .padding()
        
    }
}
import SwiftUI

struct AppStoreProductView: UIViewControllerRepresentable {

    typealias UIViewControllerType = ViewController
    
    func makeUIViewController(context: Context) -> ViewController {
        return ViewController()
    }

    func updateUIViewController(_ uiViewController: ViewController, context: Context) {
        uiViewController.openAppStore()
    }
}
import StoreKit

class ViewController: UIViewController {
    
    let appURL = URL(string: "https://itunes.apple.com/app/idxxxxxxxx")!
    let productID = xxxxxxxx

    func openAppStore() {
        
        let appStoreVC = SKStoreProductViewController()
        appStoreVC.delegate = self
        let parametersDictionary = [SKStoreProductParameterITunesItemIdentifier: productID]

        appStoreVC.loadProduct(withParameters: parametersDictionary) { loaded, error in
            guard error == nil, loaded else {
                return
            }
            self.present(appStoreVC, animated: true)
        }
    }
}

extension ViewController: SKStoreProductViewControllerDelegate {
    func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
        viewController.dismiss(animated: true)
    }
}

Many thanks in advance for any help to eliminate the blank view. Sven

I also ask the question in stackoverflow and got the hint not to use .sheet. I should call the openAppStore function directly. Here is my try but I got the following message and no App Store page comes up.

import SwiftUI

struct ContentView: View {
    
    let appStoreProductView = ViewController()
    
    var body: some View {
    
        VStack {
            Image(systemName: "apple.logo")
                .imageScale(.large)
                .onTapGesture {
                    appStoreProductView.openAppStore()
                }
                        
            Text("Hello, world!")
        }
        .padding()
    }
}

Xcode message: Attempt to present <SKStoreProductViewController: 0x10900c200> on <UpdateAppFromPlist.ViewController: 0x104d069c0> (from <UpdateAppFromPlist.ViewController: 0x104d069c0>) whose view is not in the window hierarchy.

I hope, this could be the right direction. Then I don't need struct AppStoreProductView: UIViewControllerRepresentable to create the view.

Many thanks in advance for any kind of help. Sven

I found a solution.


class AppStoreVC: UIViewController {
    
    let appURL = URL(string: "https://itunes.apple.com/app/idxxxxxxxx")
    let productID = xxxxxxxx

    func openAppStore() {
        
        let appStoreVC = SKStoreProductViewController()
        appStoreVC.delegate = self
        let parametersDictionary = [SKStoreProductParameterITunesItemIdentifier: productID]
        
        appStoreVC.loadProduct(withParameters: parametersDictionary) { _, error in
            if error != nil {
                guard let url = self.appURL else { return }
                UIApplication.shared.open(url)
            } else {
                let scene = UIApplication.shared.connectedScenes.first { $0.activationState == .foregroundActive }
                if let windowScene = scene as? UIWindowScene {
                         windowScene.keyWindow?.rootViewController?.present(appStoreVC, animated: true, completion: nil)
                }
            }
        }
    }
}

extension AppStoreVC: SKStoreProductViewControllerDelegate {
    func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
        viewController.dismiss(animated: true)
    }
}

struct ContentView: View {

    let appStoreVC = AppStoreVC()
    
    var body: some View {
    
        VStack {
            Image(systemName: "apple.logo")
                .onTapGesture {
                    appStoreVC.openAppStore()
                }
                        
            Text("Open App Store")
        }
        .padding()
    }
}
Swiftui - SKStoreProductViewController inside .sheet action open 2 views - why?
 
 
Q