What is the best way to display an alert in any view in my app when the connection is lost.
Currently using:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AppDelegate.networkStatusChanged(_:)), name: ReachabilityStatusChangedNotification, object: nil)
Reach().monitorReachabilityChanges()
func networkStatusChanged(notification: NSNotification) {
if let info = notification.userInfo as? [String:String] {
let status = info["Status"]!
if !status.containsString("Online") {
}
}
}
UIAlertViews have been deprecated, use UIAlertController instead.
let alert = UIAlertController(title: "Error", message: "You you seem to have lost internet connectivity.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .Cancel, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
Related
This question already has answers here:
how to create an alert in a swift file model that works for various view controller
(2 answers)
Closed 4 years ago.
I am trying to create a alert box inside the swift file other than the UIViewController file. but I could not create it.
extension NetworkManager {
func showAlert(message: String,from:UIViewController, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
from.present(alertController, animated: true, completion: nil)
}
}
the above code is for implementing alertcontroller but I don't know how to pass the view controller I need to present so need assistance.
extension UIViewController {
func showAlert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}
and use like this
from.showAlert(message:"Your message", title: "Title")
Add a Utilities class in your project.
class Utilities {
static func showSimpleAlert(OnViewController vc: UIViewController, Message message: String) {
//Create alertController object with specific message
let alertController = UIAlertController(title: "App Name", message: message, preferredStyle: .alert)
//Add OK button to alert and dismiss it on action
let alertAction = UIAlertAction(title: "OK", style: .default) { (action) in
alertController.dismiss(animated: true, completion: nil)
}
alertController.addAction(alertAction)
//Show alert to user
vc.present(alertController, animated: true, completion: nil)
}
}
Usage:
Utilities.showSimpleAlert(OnViewController: self, Message: "Some message")
Here is the extension I made. It allows to show either Alert or Action sheet and allows multiple actions "from the box"
extension UIViewController {
func presentAlert(title: String?, message: String, actions: UIAlertAction..., animated: Bool = true) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
actions.forEach { alert.addAction($0) }
self.present(alert, animated: animated, completion: nil)
}
func presentActionSheet(title: String?, message: String, actions: UIAlertAction..., animated: Bool = true) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
actions.forEach { alert.addAction($0) }
self.present(alert, animated: animated, completion: nil)
}
}
Usage
let delete = UIAlertAction(title: "Delete", style: .destructive, handler: { _ in /* Your code here */})
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
presentAlert(title: .albumPreferencesDeleteAlertTitle, message: "Very important message", actions: delete, cancel)
This is the more generalise method to show alert on view controller
func showAlert(msg: String, inViewController vc: UIViewController, actions: [UIAlertAction]? = nil, type: UIAlertControllerStyle = .alert, title: String = kAppName) {
let alertType: UIAlertControllerStyle = .alert
let alertTitle = kAppName
let alertVC = UIAlertController(title: alertTitle, message: msg, preferredStyle: alertType)
if let actions = actions {
for action in actions {
alertVC.addAction(action)
}
} else {
let actionCancel = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertVC.addAction(actionCancel)
}
vc.present(alertVC, animated: true, completion: nil)
}
Usage
AppUtilities.showAlert(msg: "Test msg", inViewController: self) //for alert
AppUtilities.showAlert(msg: "Test msg", inViewController: self, actions: [okAction, cancelAction]) //for alert
AppUtilities.showAlert(msg: "Test Msg", inViewController: self, type: .actionSheet) //shows action sheet
You can add this function in extension or create a separate utility class as you want.
I'm trying to limit the show of code so I just want to call function containing two strings to create a uialert faster with 1 line instead of 5/
The error I'm getting
Use of unresolved identifier 'present'
at the line
present(alert, animated: true, completion: nil)
// Controlling Alerts for Errors
func showAlert(titleString: String, messageString: String) {
// Alert to go to Settings
let alert = UIAlertController(title: titleString, message: messageString, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: { _ in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
In the comments, you explained that this is a stand-alone function. It should work if you make it an extension to UIViewController, for instance:
extension UIViewController {
public func showAlert(_ title:String, _ message:String) {
let alertVC = UIAlertController(
title: title,
message: message,
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "OK",
style: .cancel,
handler: { action -> Void in
})
alertVC.addAction(okAction)
present(
alertVC,
animated: true,
completion: nil)
}
}
And to call it in a UIViewController:
showAlert(
"Could Not Send Email",
"Your device could not send e-mail. Please check e-mail configuration and try again."
)
I'm having a problem performing an UIAlertViewController in ViewController.
This is what I currently have
func displayLoginResult(viewModel: Login.PerformLogin.ViewModel) {
endLoader(loader: loaderLogin)
if let errorMessage = viewModel.displayedError {
print(errorMessage.message)
let alert = UIAlertController(title: "Error", message: "Enter data in Text fields", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
else {
router.navigateToGroupsScene()
}
}
I've tried deleting DerivedData but nothing. I'm just considering the case that viewModel.displayedError is not nil (not the else case, just the if). I've seen if I comment this line:
self.presentViewController(alert, animated: true, completion: nil)
all works but obviously any Dialog is displayed which is not what I want. I'm a bit frustrades due to I've never had a problem like this and Xcode provides me not much information.
Exception on Xcode:
Threads details:
Any further information you need, just let me know and I will provide you!
Thank you so much.
Looks like you forgot to remove observer, add this code to your LoginViewController class:
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
Could you please try using below code:
func displayLoginResult(viewModel: Login.PerformLogin.ViewModel) {
endLoader(loader: loaderLogin)
if let errorMessage = viewModel.displayedError {
print(errorMessage.message)
let alert = UIAlertController(title: "Error", message: "Enter data in Text fields", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.presentViewController(alert, animated: true, completion: nil)
})
}
else {
router.navigateToGroupsScene()
}
}
Hello I have a utility class in which I have declared AlertViewFunction like this
func displayAlertMessage(userMessage: String,//controller){
let myAlert = UIAlertController(title: "Alert", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil)
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
}
The problem is I can't use self here
self.presentViewController(myAlert, animated: true, completion: nil)
I want to pass a controller to this function so I can use like this
controller.presentViewController(myAlert, animated: true, completion: nil)
How Can I pass a controller from any ViewController. Lets say If I am in LoginViewController
Utility().displayAlertMessage(Message.INTERNETISNOTCONNECTED,//controller)
Utility().displayAlertMessage(Message.INTERNETISNOTCONNECTED, controller: self)
and
func displayAlertMessage(userMessage: String, controller: UIViewController)
{
controller?.presentViewController(myAlert, animated: true, completion: nil)
}
pass in the view controller as an argument to the function.
func displayAlertMessage(controller: UIViewController, title: String, message: String?) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
alert.addAction(okAction)
controller.presentViewController(alert, animated: false, completion: nil)
}
Alternatively you can even return the alert to the caller of the function for further customization by saying:
func displayAlertMessage(title: String, message: String?) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
alert.addAction(okAction)
return alert
}
class controller: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let alert = displayAlertMessage("title", message: nil)
presentViewController(alert, animated: true, completion: nil)
}
}
I'm using Reachability of ashleymills: https://github.com/ashleymills/Reachability.swift/releases
In Xcode 7, I wrote a function to display an alert of reachability status.
However, the alert never shows up.
Here is my code:
let reachability = Reachability.reachabilityForInternetConnection()
reachability!.whenReachable = { reachability in
if reachability.isReachableViaWiFi() {
let alertController = UIAlertController(title: "Alert", message: "Reachable via WiFi", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
else {
let alertController = UIAlertController(title: "Alert", message: "Reachable via Cellular", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
reachability!.whenUnreachable = { reachability in
let alertController = UIAlertController(title: "Alert", message: "Please connect to internet", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
reachability!.startNotifier()
Please replace your code with this and it should work, there might be a bug in Reachability after swift 1.2, so here I'm just checking if its reachable or not and i think its enough.
In my opinion you don't have to check if its the wifi or cellular, The reason behind the alert isn't showing because its not entering the blocks to show the alert :
let useClosures = false
class ViewController: UIViewController {
let reachability = Reachability.reachabilityForInternetConnection()
override func viewDidLoad() {
super.viewDidLoad()
if (useClosures) {
reachability?.whenReachable = { reachability in
print("Reachable")
}
reachability?.whenUnreachable = { reachability in
print("Unreachable")
}
} else {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: ReachabilityChangedNotification, object: reachability)
}
reachability?.startNotifier()
// Initial reachability check when the app starts
if let reachability = reachability {
dispatch_async(dispatch_get_main_queue()) {
if reachability.isReachable() {
let alertController = UIAlertController(title: "Alert", message: "Reachable", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Alert", message: "Please connect to internet", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}
}
deinit {
reachability?.stopNotifier()
if (!useClosures) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: ReachabilityChangedNotification, object: nil)
}
}
func reachabilityChanged(note: NSNotification) {
let reachability = note.object as! Reachability
// Initial reachability check while surfing in the app
if reachability.isReachable() {
let alertController = UIAlertController(title: "Alert", message: "Reachable", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Alert", message: "Please connect to internet", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}
Note : You said you have webView in your app, remember that you have to refresh or update when its reachable.