1 Reply
      Latest reply on Sep 24, 2019 10:29 AM by OOPer
      vixenaga Level 1 Level 1 (0 points)

        Hi,

        After ios 13 release I retested my app and I am getting an error which was not on previous versions of ios:

         

        Main Thread Checker: UI API called on a background thread: -[UIPageViewController setViewControllers:direction:animated:completion:]

        and

        Main Thread Checker: UI API called on a background thread: -[UIPageViewController setViewControllers:direction:animated:completion:]

        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.'

         

        Here is the code:

        @IBAction func nextButtonTapped(_ sender: UIButton) {

                let onboardingPager = self.parent as! OnboardingPager

         

         

                var purchased = Bool(false)

                DoctorSugarProducts.store.requestProducts{ [weak self] success, products in

                    guard let self = self else { return }

                    if success {

                        //self.products = products!

                        for product in products! {

                            if DoctorSugarProducts.store.isProductPurchased(product.productIdentifier) {

                                purchased = true

                            }

                        }

                 

                        if purchased == false {

                            //onboardingPager.transition(from: onboardingPager.getStepZero(), to: onboardingPager.getStepOne(), duration: 0, options: [], animations: nil, completion: nil)

                            onboardingPager.setViewControllers([onboardingPager.getStepOne()], direction: .forward, animated: true, completion: nil)

                        } else {

                            onboardingPager.setViewControllers([onboardingPager.getStepTwo()], direction: .forward, animated: true, completion: nil)

                        }

                    } else {

                        onboardingPager.setViewControllers([onboardingPager.getStepTwo()], direction: .forward, animated: true, completion: nil)

                    }

                }

         

            }

         

        Line causing the problem is the last line:  onboardingPager.setViewControllers([onboardingPager.getStepTwo()], direction: .forward, animated: true, completion: nil)

         

        Products requested are products from SKProductsRequestDelegate.

         

        Does anyone have similar problem and knows what to do about it?

        • Re: Terminating app due to uncaught exception 'NSInternalInconsistencyException'
          OOPer Level 8 Level 8 (5,415 points)

          I have not experienced exactly the same issue, but the fix seems to be clear.

           

          Do all the UI API calls and possibly thread-unsafe operations on the main thread.

           

          Something like this:

              @IBAction func nextButtonTapped(_ sender: UIButton) {
                  let onboardingPager = self.parent as! OnboardingPager
                  
                  DoctorSugarProducts.store.requestProducts{ success, products in
                      DispatchQueue.main.async {
                          if success {
                              let purchased = (products ?? []).contains {
                                  DoctorSugarProducts.store.isProductPurchased($0.productIdentifier)
                              }
                              
                              if !purchased {
                                  onboardingPager.setViewControllers([onboardingPager.getStepOne()], direction: .forward, animated: true, completion: nil)
                              } else {
                                  onboardingPager.setViewControllers([onboardingPager.getStepTwo()], direction: .forward, animated: true, completion: nil)
                              }
                          } else {
                              onboardingPager.setViewControllers([onboardingPager.getStepTwo()], direction: .forward, animated: true, completion: nil)
                          }
                      }
                  }
              }

          Some changes other that putting `DispatchQueue.main.async {...}` are just for my preference, but I believe you have no need to use `[weak self]` in your case.