Skip to content

Instantly share code, notes, and snippets.

@JasonCanCode
Last active August 3, 2018 15:52
Show Gist options
  • Save JasonCanCode/b0071a3236240b460b8512ec7be85397 to your computer and use it in GitHub Desktop.
Save JasonCanCode/b0071a3236240b460b8512ec7be85397 to your computer and use it in GitHub Desktop.
A convenient way to create and present AlertControllers.
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)
}
}
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