在后台异步呈现视图控制器

Present view controller asynchronously in background

我发送一个异步请求,并在收到成功时显示一个视图控制器。有效。

但是我遇到了一个问题,当我收到成功时我的应用程序处于后台并且我在前台传递它。视图控制器并不总是显示。

我认为是关于主线程的,但我不确定。

我该如何解决?

编辑:

成功后调用的函数如下:

func showPopup(on viewController: UIViewController) {
    let viewControllerToPresent = MyPopupViewController(nibName: "Popup", bundle: nil)

    let popup = PopupDialog(viewController: viewControllerToPresent, buttonAlignment: .horizontal, transitionStyle: .zoomIn, gestureDismissal: false)

    let button = DefaultButton(title: "Ok") {
        popup.dismiss(animated: true, completion: nil)
    }

    popup.addButtons([button])
    viewController.present(popup, animated: true, completion: nil)
}

如果您从后台调用 UI 函数,结果是不可预测的。只是显式地出现在主线程上。这是一个简化的例子:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.doBackgroundStuff()
    }

    func getThread() -> String {
        return Thread.isMainThread ? "UI" : "BG"
    }

    func doBackgroundStuff() {
        // force to background
        DispatchQueue.global().async {
            print("doBackgroundStuff: this is the \(self.getThread()) thread")
            self.showPopup(on: self)
        }
    }

    func showPopup(on viewController: UIViewController) {
        print("showPopup OUTER: this is the \(self.getThread()) thread")
        // force to foreground
        DispatchQueue.main.sync {
            print("showPopup INNER: this is the \(self.getThread()) thread")
            let popup = PresentingViewController(nibName: "PresentingViewController", bundle: nil)
            viewController.present(popup, animated: true, completion: nil)
        }
    }
}

显示 UI 并且控制台上的输出是:

doBackgroundStuff: this is the BG thread
showPopup OUTER: this is the BG thread
showPopup INNER: this is the UI thread

当您的应用程序处于后台时,即暂停时,Apple 不允许您对用户界面进行任何实质性更改。在这种情况下,您最好的方法可能是保存您想要在 return 上执行某些操作并检查您的 App Delegates applicationDidBecomeActive 方法。