Home > Blockchain >  Modifications to the layout engine must not be performed from a background thread after it has been
Modifications to the layout engine must not be performed from a background thread after it has been

Time:11-01

I am using in app purchase in my application,

code: i have added IAP in signin and capability and added subscription in appstore connect and used below code.. its working fine in iOS 13 but its hitting crash in iOS 15.2.. like below out put screen its showing and then its crashed

i have added DispatchQueue.main.async in some places but still no luck its crashing... for IAP i am not getting enough refarances also, please guide me

import StoreKit
import UIKit
class BuyProfileBoosterVC: UIViewController, SKPaymentTransactionObserver, SKProductsRequestDelegate {

var products = [SKProduct]()
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
    products = response.products
    showSingleButtonWithMessage(title: "Alert", message: "You have total \(products.count) product in App Store connect.", buttonName: "Okay")
}

override func viewDidLoad() {
    super.viewDidLoad()
    DispatchQueue.main.async{
        SKPaymentQueue.default().add(self)
    }
}

enum Products: String, CaseIterable {
    case threeDays
}
// MARK: - Popup related
func fetchProduct() {
    let request = SKProductsRequest(productIdentifiers: Set(Products.allCases.compactMap({$0.rawValue})))
    request.delegate = self
    request.start()
}
func buyProduct(productId: String) {
    fetchProduct()
    DispatchQueue.main.async{
        if SKPaymentQueue.canMakePayments() {
            let paymentRequest = SKMutablePayment()
            paymentRequest.productIdentifier = productId
            SKPaymentQueue.default().add(paymentRequest)
        }
        else {
            self.view.makeToast("You can't make payment.")
        }
    }
}

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    
    DispatchQueue.main.async
    {
        transactions.forEach { (transaction) in
            switch transaction.transactionState {
            case .purchasing: self.view.makeToast("Transaction started.")
            case .purchased, .restored: self.view.makeToast("Transaction successful/restored.")
            case .failed, .deferred: self.view.makeToast("Transaction failed.")
            @unknown default: self.view.makeToast("Unknown state.")
            }
        }
    }
}

@IBAction func jumpBuyAction(_ sender: UIButton) {
    DispatchQueue.main.async {
        self.fetchProduct()
        self.buyProduct(productId: "threeDay")
    }
}
}

Error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.' terminating with uncaught exception of type NSException

Out put of screen

CodePudding user response:

Apple Developer Documentation is the best resource for IAP in IOS but also you can have a look at this tutorial if you want to find a relatively easy one.

About the crash, as there is not much information available from your code but it might be crashing on showSingleButtonWithMessage function call, This is something that is supposed to be done on main thread( assuming this shows an alert controller ) and where it is called in your code, it might be getting called on background thread. Try calling it on main thread.

  • Related