UIAlertController.swift 2.7 KB

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