func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
hideActivity()
let products = response.products
if products.count > 0{
let controller = HAPurchaseViewController.instantiate() // crashes here
controller.categories = dataManager.paidCategories()
controller.products = products
self.navigationController?.pushViewController(controller, animated: true)
}
else{
DispatchQueue.main.async { [weak self] in
let alertController = UIAlertController(title: "Oops!", message: "Unable to load or products not found, please try again later", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default)
alertController.addAction(okAction)
self?.present(alertController, animated: true)
}
}
}
This extension works everywhere else except when I am using it to load my In App Purchase View Controller.
import Foundation
import UIKit
protocol Storyboarded {
static func instantiate() -> Self
}
extension Storyboarded where Self: UIViewController {
static func instantiate() -> Self {
let id = String(describing: self)
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if #available(iOS 13.0, *) {
return storyboard.instantiateViewController(identifier: id) as! Self // App crash here when loading storyboard
} else {
return storyboard.instantiateViewController(withIdentifier: id) as! Self
}
}
static func value() -> Self {
return UIViewController() as! Self
}
}
=================================================================
Main Thread Checker: UI API called on a background thread: -[UIViewController initWithCoder:] > PID: 13525, TID: 4347723, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0
Backtrace:
After the advice from SO, I updated the code
extension Storyboarded where Self: UIViewController {
static func instantiate() -> Self {
DispatchQueue.main.async {
let id = String(describing: self)
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if #available(iOS 13.0, *) {
return storyboard.instantiateViewController(identifier: id) as! Self
} else {
return storyboard.instantiateViewController(withIdentifier: id) as! Self
}
}
}
static func value() -> Self {
return UIViewController() as! Self
}
}