PresentAlertAction.swift 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /// Presents an alert to the user.
  2. ///
  3. /// Returns once an action has been selected and the corresponding action
  4. /// handler has been run. Returns the index of the selected action. By default,
  5. /// the alert will have a single button labelled "OK". All buttons will dismiss
  6. /// the alert even if you provide your own actions.
  7. @MainActor
  8. public struct PresentAlertAction {
  9. let environment: EnvironmentValues
  10. /// Presents an alert to the user.
  11. ///
  12. /// - Parameters:
  13. /// - title: The title of the alert.
  14. /// - actions: A list of actions the user can perform.
  15. /// - Returns: The index of the chosen action.
  16. @discardableResult
  17. public func callAsFunction(
  18. _ title: String,
  19. @AlertActionsBuilder actions: () -> [AlertAction] = { [.default] }
  20. ) async -> Int {
  21. let actions = actions()
  22. func presentAlert<Backend: BackendFeatures.Alerts>(backend: Backend) async -> Int {
  23. await withCheckedContinuation { continuation in
  24. backend.runInMainThread {
  25. let alert = backend.createAlert()
  26. backend.updateAlert(
  27. alert,
  28. title: title,
  29. actionLabels: actions.map(\.label),
  30. environment: environment
  31. )
  32. let window = environment.window.map { $0 as! Backend.Window }
  33. backend.showAlert(alert, window: window) { actionIndex in
  34. actions[actionIndex].action()
  35. continuation.resume(returning: actionIndex)
  36. }
  37. }
  38. }
  39. }
  40. guard let backend = environment.backend as? any BackendFeatures.Alerts else {
  41. fatalError("\(type(of: environment.backend)) does not support alerts")
  42. }
  43. return await presentAlert(backend: backend)
  44. }
  45. }