swift - 导航到另一个 xib 时未在 AppKit(主)线程问题上运行

标签 swift macos swift4 xib safari-extension

我的应用程序的用例是有一个登录用户界面,它在 SafariExtensionViewController.xib 中处理,当用户点击登录按钮时,必须显示另一个用户界面,即 ExtensionStepsViewController .xib。我使用以下导航到另一个屏幕

self.presentViewControllerAsSheet(ExtensionStepsViewController())

但是,我遇到了以下问题

  • Assertion failure in void assertRunningOnAppKitThread(void)(), 2018-09-05 15:02:30.318742+0545 extension[13150:1422110] [General] not running on AppKit (main) thread

这是我的代码

SafariExtensionViewController.swift

import SafariServices

class SafariExtensionViewController: SFSafariExtensionViewController {


    @IBOutlet weak var passwordMessage: NSTextField!
    @IBOutlet weak var emailMessage: NSTextField!
    @IBOutlet weak var message: NSTextField!
    @IBOutlet weak var email: NSTextField!
    @IBOutlet weak var password: NSSecureTextField!
    static let shared = SafariExtensionViewController()
    override func viewDidLoad() {
        message.stringValue = ""
        emailMessage.stringValue = ""
        passwordMessage.stringValue = ""
    }


    @IBAction func userLogin(_ sender: Any) {
        let providedEmailAddress = email.stringValue
        let providedPassword = password.stringValue
        let isEmailAddressValid = isValidEmailAddress(emailAddressString: providedEmailAddress)
        self.message.stringValue = ""
        emailMessage.stringValue = ""
        passwordMessage.stringValue = ""
        if isEmailAddressValid && providedPassword.count > 0 {
            let session = URLSession.shared
            var request = URLRequest(url: URI!)
            request.httpMethod = "POST"
            do {
                request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
            } catch let error {
                print(error.localizedDescription)
            }
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

                guard error == nil else {
                    return
                }

                guard let data = data else {
                    return
                }

                do {
                    //create json object from data
                    if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                        if let httpResponse = response as? HTTPURLResponse {
                            if (httpResponse.statusCode >= 200 && httpResponse.statusCode < 300) {
                                print("#########LOGIN########################")
                                self.message.stringValue = "Login Successful"
                                self.message.textColor = NSColor.green

                                UserDefaults.standard.set(providedEmailAddress, forKey: "email")
                                self.presentViewControllerAsSheet(ExtensionStepsViewController()) // error is thrown after this action
                            } else {
                                self.message.stringValue = "Invalid Credentials"
                                self.message.textColor = NSColor.red
                            }
                        }
                        // handle json...
                    }
                } catch let error {
                    print(error.localizedDescription)
                }
            })
            task.resume()
        } else {
            emailMessage.textColor = NSColor.red
            emailMessage.stringValue = "Invalid Email"
        }
    }

  }

ExtensionStepsViewController.swift

import SafariServices

class ExtensionStepsViewController: SFSafariExtensionViewController {

//    static let shared = SafariExtensionViewController()
    override func viewDidLoad() {
        super.viewDidLoad()
        print("Hello") // this is also printed 
        // Do view setup here.
    }

}

当登录成功然后执行此语句 self.presentViewControllerAsSheet(ExtensionStepsViewController()) print("hello") 在调试部分打印,我获取列出的问题。

最佳答案

UI 的所有更新都必须从主线程完成。似乎 completionHandler 没有在主线程上调用,这导致此断言失败。

您需要在主队列中执行演示。您可以按如下方式安排 block 来做到这一点:

DispatchQueue.main.async {
  // This will  now run on the main queue.
  self.presentViewControllerAsSheet(ExtensionStepsViewController())
}

关于swift - 导航到另一个 xib 时未在 AppKit(主)线程问题上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52181959/

相关文章:

ios - 在 iOS 中创建标签栏导航的最佳实践是什么

ios - SKStoreProductViewController 取消按钮留下白色空白屏幕

swift - 可以在不使用 'Static' 的情况下创建单例类吗?

ios - Swift:如何在动态 UITableView 中使用静态单元格

macos - 我的 boot2docker 安装似乎无法正常工作。我究竟做错了什么?

regex - sed 命令行 将 "aas=aas"更改为 "aas = aas"

ios - 使用 Core Location 在 Apple Watch 上获得精确的室内位置更新?

iphone - 观察 CALayer 中的动画属性变化

ios - 返回类实例的 switch 语句

arrays - Swift - 根据值连接两个元组数组