I ended up finding a solution for UIKit through the hints from @jpdev001. The fix involves two key components:
Creating a hidden UIWindow that provides the necessary context for StoreKit operations. This window is kept at a lower window level but maintains key status.
Wrapping the presenting view controller in a UINavigationController, which iOS 18.2's StoreKit requires for proper purchase flow.
I created a reusable protocol and utility function that handles this automatically. The function takes care of creating the hidden window, managing the navigation controller setup, and setting the requested presentation styles.
protocol Navigatable: UIViewController {
var displayedWindow: UIWindow? { get set }
}
extension UIViewController {
func presentWithStoreKitSupport<T: Navigatable>(
from presentingView: UIViewController,
viewController: T,
presentationStyle: UIModalPresentationStyle,
isModalInPresentation: Bool = false,
transitionStyle: UIModalTransitionStyle? = nil,
animated: Bool = true
) {
// Create navigation controller
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.isNavigationBarHidden = true
navigationController.modalPresentationStyle = presentationStyle
navigationController.isModalInPresentation = isModalInPresentation
if let transitionStyle = transitionStyle {
navigationController.modalTransitionStyle = transitionStyle
}
// Create StoreKit context window
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
let purchaseWindow = UIWindow(windowScene: windowScene)
purchaseWindow.isHidden = true
purchaseWindow.windowLevel = .normal - 1
purchaseWindow.rootViewController = UIViewController()
purchaseWindow.makeKeyAndVisible()
// Store window reference
viewController.displayedWindow = purchaseWindow
// Present the navigation controller
presentingView.present(navigationController, animated: animated)
}
}
}
The transition to the respective view can be implemented the following way:
view.presentWithStoreKitSupport(
from: view, // the main view
viewController: navigatingView, // view we intend to navigate to
presentationStyle: .fullScreen
)
Using this approach for the views that include in-app purchases fixed the issue for me. The solution also still works for older iOS Versions (tested with iOS 15 an 17). Also tested on multiple physical devices (iPhone 12 Pro and 15 Pro).
Post
Replies
Boosts
Views
Activity
Very late to the answer but the solution was to simply add a UITapGestureRecognizer:
let tapGesture = UITapGestureRecognizer(target: self, action: action)
button.addGestureRecognizer(tapGesture)
Running into the same issue with iOS 18.2 using UIKit (Purchases work as expected with iOS 18.1).
I have my purchases in views that are shown as
.modalPresentationStyle = .pageSheet and .modalPresentationStyle = .fullScreen. Tried other presentation styles but i keep getting "Could not get confirmation scene ID for" followed by the error "unknown".