KMAlertTool.swift 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // KMAlertTool.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2023/12/7.
  6. //
  7. import Cocoa
  8. class KMAlertTool: NSObject {
  9. /*
  10. * NSAlert 弹窗封装
  11. * 主线程执行
  12. */
  13. public class func runModel(style: NSAlert.Style = .critical, message: String, informative: String = "", buttons: [String] = [], callback: @escaping ((NSApplication.ModalResponse)->Void)) {
  14. let block = {
  15. let result = Self._runModelForMainThread(style: style, message: message, informative: informative, buttons: buttons)
  16. callback(result)
  17. }
  18. if Thread.isMainThread {
  19. block()
  20. } else {
  21. Task { @MainActor in
  22. block()
  23. }
  24. }
  25. }
  26. /*
  27. * NSAlert 弹窗封装
  28. * 主线程执行
  29. * 异步函数
  30. */
  31. @available(macOS 10.15.0, iOS 13.0, *)
  32. public class func runModel(style: NSAlert.Style = .critical, message: String, informative: String = "", buttons: [String] = []) async -> NSApplication.ModalResponse {
  33. return await withCheckedContinuation({ continuation in
  34. self.runModel(style: style, message: message, informative: informative, buttons: buttons) { response in
  35. continuation.resume(returning: response)
  36. }
  37. })
  38. }
  39. /*
  40. * NSAlert 弹窗封装
  41. * 主线程调用
  42. * 无返回值
  43. */
  44. public class func runModelForMainThread(style: NSAlert.Style = .critical, message: String, informative: String = "", buttons: [String] = []) {
  45. _ = self._runModelForMainThread(style: style, message: message, informative: informative, buttons: buttons)
  46. }
  47. /*
  48. * NSAlert 弹窗封装
  49. * 主线程调用
  50. * 有返回值
  51. */
  52. public class func runModelForMainThread_r(style: NSAlert.Style = .critical, message: String, informative: String = "", buttons: [String] = []) -> NSApplication.ModalResponse {
  53. return self._runModelForMainThread(style: style, message: message, informative: informative, buttons: buttons)
  54. }
  55. // MARK: - Private Methods
  56. /*
  57. * NSAlert 弹窗封装
  58. * 主线程调用
  59. */
  60. private class func _runModelForMainThread(style: NSAlert.Style = .critical, message: String, informative: String = "", buttons: [String] = []) -> NSApplication.ModalResponse {
  61. // if Thread.isMainThread == false {
  62. // #if DEBUG
  63. // assert(false, "need main thread doing ...")
  64. // #endif
  65. // return .stop
  66. // }
  67. // 确保在主线程上执行
  68. guard Thread.isMainThread else {
  69. var resp: NSApplication.ModalResponse = .abort
  70. DispatchQueue.main.sync {
  71. resp = _runModelForMainThread(style: style, message: message, informative: informative, buttons: buttons)
  72. }
  73. return resp
  74. }
  75. // 参数有效性检查
  76. // guard !buttons.isEmpty else {
  77. // assertionFailure("Buttons array should not be empty")
  78. // return .abort
  79. // }
  80. let alert = NSAlert()
  81. alert.alertStyle = style
  82. alert.messageText = message
  83. alert.informativeText = informative
  84. for title in buttons {
  85. alert.addButton(withTitle: title)
  86. }
  87. return alert.runModal()
  88. }
  89. }