swift - 导航到另一个 xib 时未在 AppKit(主)线程问题上运行
问题描述
我的应用程序的用例是有一个登录 ui,SafariExtensionViewController.xib
当用户点击登录按钮时,必须显示另一个 UI,即ExtensionStepsViewController.xib
. 我使用以下导航到另一个屏幕
self.presentViewControllerAsSheet(ExtensionStepsViewController())
但是,我遇到了以下问题
- 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
没有在主线程上调用,这导致此断言失败。
您需要在主队列上进行演示。您可以通过如下安排一个块来做到这一点:
DispatchQueue.main.async {
// This will now run on the main queue.
self.presentViewControllerAsSheet(ExtensionStepsViewController())
}
推荐阅读
- python - 我想通过使用 lambda 更改此 def
- python - python如何从main调用函数
- c# - 如何在 C# 中为 GC 正确固定对象以防止 AccessViolationException?
- php - 会话不会在 laravel 5.6 中刷新/保留
- nuxt.js - Nuxt 使用 vuex 和多语言站点生成
- tensorflow - 如何使用 tf.strategy 修改 Keras CycleGAN 示例代码以在 GPU 上并行运行
- javascript - Django Rest Framework Path 适用于一个链接,但不适用于具有相同设置的其他链接
- python-3.x - 当特定 ID 在其他列中有标志 X 时,查找该 ID 的天数间隔
- svg - 使用 CSS、Javascript 使 SVG 可点击但不可拖动
- javascript - 仅显示一个属性,但保存整个对象(React Final Form + Downshift)