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.
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.
Iphone app rejected because of the the reason that
“We discovered one or more bugs in your app when reviewed on iPad and iPhone running iOS 10.0 on Wi-Fi connected to an IPv6 network.”
Anyone can help to solve it?
import UIKit
let useClosures = false
class ViewController: UIViewController {
let reachability = Reachability.reachabilityForInternetConnection()
#IBOutlet weak var WebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.backgroundColor = UIColor.redColor()
let URL = NSURL(string: "https://gph-shop.com/tracing")
WebView.loadRequest(NSURLRequest(URL: URL!))
if (useClosures) {
reachability?.whenReachable = { reachability in
print("Reachable")
}
reachability?.whenUnreachable = { reachability in
print("Unreachable")
}
} else {
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.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: "", message: "wi-fi connected", 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)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You need to debug your app in a NAT64 Network.
(You can create it by using your macOS.)
And Apple support article is following:
https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html
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)
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 have the following button action in a toolbar:
#IBAction func share(sender: AnyObject) {
let modifiedURL1 = "http://www.declassifiedandratified.com/search.html?q=\(self.searchBar.text)"
let modifiedURL = modifiedURL1.stringByReplacingOccurrencesOfString(" ", withString: "%20", options: NSStringCompareOptions.LiteralSearch, range: nil)
let alert = UIAlertController(title: "Share", message: "Share your findings", preferredStyle: UIAlertControllerStyle.ActionSheet)
let twBtn = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default) { (alert) -> Void in
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter){
var twitterSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
twitterSheet.setInitialText("Look what I found on Declassified and Ratified: \(modifiedURL)")
self.presentViewController(twitterSheet, animated: true, completion: nil)
} else {
var alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to share.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
let fbBtn = UIAlertAction(title: "Facebook", style: UIAlertActionStyle.Default) { (alert) -> Void in
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook){
var facebookSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
facebookSheet.setInitialText("Look what I found on Declassified and Ratified: \(modifiedURL)")
self.presentViewController(facebookSheet, animated: true, completion: nil)
} else {
var alert = UIAlertController(title: "Accounts", message: "Please login to a Facebook account to share.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
let safariBtn = UIAlertAction(title: "Open in Safari", style: UIAlertActionStyle.Default) { (alert) -> Void in
let URL = NSURL(string: modifiedURL)
UIApplication.sharedApplication().openURL(URL!)
}
let cancelButton = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (alert) -> Void in
println("Cancel Pressed")
}
let textBtn = UIAlertAction(title: "Message", style: UIAlertActionStyle.Default) { (alert) -> Void in
if (MFMessageComposeViewController.canSendText()) {
let controller = MFMessageComposeViewController()
controller.body = "Look what I found on Declassified and Ratified: \(modifiedURL)"
controller.messageComposeDelegate = self
self.presentViewController(controller, animated: true, completion: nil)
}
}
alert.addAction(twBtn)
alert.addAction(fbBtn)
alert.addAction(safariBtn)
alert.addAction(textBtn)
alert.addAction(cancelButton)
self.presentViewController(alert, animated: true, completion: nil)
}
However, this code crashes when called on an iPad with a sigbart crash (that is all I can see in the console). I see this is a common problem but the other solutions have not worked for me. I even set the version to the latest iOS and that didn't fix it. Can someone explain?
On an iPad, an action sheet is a popover. Therefore you must give its UIPopoverPresentationController a sourceView and sourceRect, or barButtonItem, so that it has something to attach its arrow to.