UIAlertController.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //
  2. // UIAlertController.swift
  3. // LoopKitUI
  4. //
  5. // Created by Pete Schwamb on 1/22/19.
  6. // Copyright © 2019 LoopKit Authors. All rights reserved.
  7. //
  8. import Foundation
  9. extension UIAlertController {
  10. /// Convenience method to initialize an alert controller to display an error
  11. ///
  12. /// - Parameters:
  13. /// - error: The error to display
  14. /// - title: The title of the alert. If nil, the error description will be used.
  15. /// - helpAnchorHandler: An optional closure to be executed when a user taps to open the error's `helpAnchor`
  16. /// - url: A URL created from the error's helpAnchor property
  17. public convenience init(with error: Error, title: String? = nil, helpAnchorHandler: ((_ url: URL) -> Void)? = nil) {
  18. var actions: [UIAlertAction] = []
  19. let errorTitle: String
  20. let message: String
  21. if let error = error as? LocalizedError {
  22. let sentenceFormat = LocalizedString("%@.", comment: "Appends a full-stop to a statement")
  23. let messageWithRecovery = [error.failureReason, error.recoverySuggestion].compactMap({ $0 }).map({
  24. String(format: sentenceFormat, $0)
  25. }).joined(separator: "\n")
  26. if messageWithRecovery.isEmpty {
  27. message = error.localizedDescription
  28. } else {
  29. message = messageWithRecovery
  30. }
  31. if let helpAnchor = error.helpAnchor, let url = URL(string: helpAnchor), let helpAnchorHandler = helpAnchorHandler {
  32. actions.append(UIAlertAction(
  33. title: LocalizedString("More Info", comment: "Alert action title to open error help"),
  34. style: .default,
  35. handler: { (_) in helpAnchorHandler(url) }
  36. ))
  37. }
  38. errorTitle = (error.errorDescription ?? error.localizedDescription).localizedCapitalized
  39. } else {
  40. // See: https://forums.developer.apple.com/thread/17431
  41. // The compiler automatically emits the code necessary to translate between any ErrorType and NSError.
  42. let castedError = error as NSError
  43. errorTitle = error.localizedDescription.localizedCapitalized
  44. message = castedError.localizedRecoverySuggestion ?? String(describing: error)
  45. }
  46. self.init(title: title ?? errorTitle, message: message, preferredStyle: .alert)
  47. let action = UIAlertAction(
  48. title: LocalizedString("com.loudnate.LoopKit.errorAlertActionTitle", value: "OK", comment: "The title of the action used to dismiss an error alert"), style: .default)
  49. addAction(action)
  50. self.preferredAction = action
  51. for action in actions {
  52. addAction(action)
  53. }
  54. }
  55. }