Last active
August 3, 2018 15:52
-
-
Save JasonCanCode/b0071a3236240b460b8512ec7be85397 to your computer and use it in GitHub Desktop.
A convenient way to create and present AlertControllers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
extension UIAlertAction { | |
convenience init(title: String, handler: ((UIAlertAction?) -> Void)? = nil) { | |
self.init(title: title, style: .default, handler: handler) | |
} | |
} | |
/// - Tag: AlertHelper | |
struct AlertHelper { | |
private static var closeButtonText = Constants.Alert.closeButtonText | |
private static var cancelButtonText = Constants.Alert.cancelButtonText | |
private static var affirmativeButtonText = Constants.Alert.affirmativeButtonText | |
private static var settingsButtonText = Constants.Alert.settingsButtonText | |
// MARK: Actionable Alerts | |
static func showSingleButtonAlert(in viewController: UIViewController, | |
title: String?, | |
message: String?, | |
dismissLabel: String = closeButtonText, | |
completion: @escaping (() -> Void) = {}) { | |
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) | |
// The completion block of a UIAlertController is called when the alert is displayed, not when it is dismissed. | |
// In this way, you cannot dismiss a viewController that has presented the alert until after it is dismissed. | |
alert.addAction(UIAlertAction(title: dismissLabel, handler: { _ in | |
// Dismiss ViewController that presented the alert here. | |
completion() | |
})) | |
viewController.present(alert, animated: true, completion: nil) | |
} | |
static func showConfirmationAlert(in viewController: UIViewController, | |
title: String?, | |
message: String?, | |
confirmationActionText actionText: String = affirmativeButtonText, | |
cancelActionText: String = cancelButtonText, | |
confirmationActionHandler handler: @escaping (UIAlertAction?) -> Void) { | |
let positiveAction = UIAlertAction(title: actionText, style: .default, handler: handler) | |
let cancelAction = UIAlertAction(title: cancelActionText, style: .cancel) | |
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) | |
alert.addAction(positiveAction) | |
alert.addAction(cancelAction) | |
alert.preferredAction = positiveAction | |
viewController.present(alert, animated: true) {} | |
} | |
// MARK: Settings | |
static func showSettingsAlert(in viewController: UIViewController, title: String?, message: String?, fallbackMessage: String? = nil) { | |
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString), | |
UIApplication.shared.canOpenURL(settingsUrl) else { | |
showSingleButtonAlert(in: viewController, title: title, message: fallbackMessage ?? message) | |
return | |
} | |
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) | |
let settingsAction = UIAlertAction(title: settingsButtonText) { _ in | |
if #available(iOS 10.0, *) { | |
UIApplication.shared.open(settingsUrl, completionHandler: nil) | |
} else { | |
UIApplication.shared.openURL(settingsUrl) | |
} | |
} | |
alert.addAction(settingsAction) | |
alert.addAction(UIAlertAction(title: closeButtonText)) | |
viewController.present(alert, animated: true, completion: nil) | |
} | |
// MARK: Error Alerts | |
static func showAlert(for error: Error, | |
in viewController: UIViewController, | |
title: String? = nil, | |
dismissLabel: String = closeButtonText) { | |
if let customError = error as? CustomError { | |
return showAlert(for: customError, in: viewController) | |
} | |
let error = error as NSError | |
let alertTitle: String | |
let alertMessage: String | |
if let errorTitle = error.userInfo["title"] as? String, let errorMessage = error.userInfo["detail"] as? String { | |
alertTitle = title ?? errorTitle | |
alertMessage = errorMessage | |
} else { | |
alertTitle = title ?? String(format: "Error %i", error.code) | |
alertMessage = error.localizedDescription | |
} | |
let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) | |
alert.addAction(UIAlertAction(title: dismissLabel)) | |
viewController.present(alert, animated: true) | |
} | |
static func showAlert(for error: CustomError, in viewController: UIViewController) { | |
let isUnauthorizedError = error.localizedDescription == NetworkError.unauthorized.localizedDescription | |
if isUnauthorizedError {//} && isLoggedIn { | |
return | |
} | |
let alert = UIAlertController(title: error.title, message: error.localizedDescription, preferredStyle: .alert) | |
alert.addAction(UIAlertAction(title: closeButtonText)) | |
viewController.present(alert, animated: true) | |
} | |
// MARK: Private Helpers | |
private static func alertTitle(for error: Error) -> String { | |
let error = error as NSError | |
return String(format: "Error %i", error.code) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/// Used with Alert Helper to easily recognize and display custom error alerts | |
protocol CustomError: LocalizedError { | |
var title: String { get } | |
var localizedDescription: String { get } | |
} | |
extension CustomError { | |
var title: String { | |
return "Error" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment