检测 Internet 连接并显示 UIAlertview Swift 3

Posted

技术标签:

【中文标题】检测 Internet 连接并显示 UIAlertview Swift 3【英文标题】:Detect Internet Connection and display UIAlertview Swift 3 【发布时间】:2016-11-13 15:46:20 【问题描述】:

我正在制作一个应用程序,该应用程序通过使用 if else 语句来检测是否有互联网连接,当有互联网时,什么都不做,但如果没有互联网连接,则警报视图显示该应用程序需要我管理的互联网发现可达性但要在我的 viewDidLoad() 上实现 uialertview 似乎不起作用。 我正在使用这个:

public class Reachability 
class func isConnectedToNetwork() -> Bool 
    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) 
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        
    
    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
    if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false 
        return false
    
    let isReachable = flags == .reachable
    let needsConnection = flags == .connectionRequired
    return isReachable && !needsConnection
    

然后在我的 View Controller 类中:

override func viewDidLoad() 
        if Reachability.isConnectedToNetwork() == true
        
            print("Connected")
        
        else
        
            let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
            let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
            let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

            controller.addAction(ok)
            controller.addAction(cancel)

            present(controller, animated: true, completion: nil)
        
        super.viewDidLoad()
        //...
    

并且看起来警报视图没有弹出 有什么建议吗?或帮助? 谢谢

【问题讨论】:

尝试使用viewDidAppear 而不是viewDidLoad @rmaddy 你能详细说明一下吗?我是 swift 或 ios 的新手,我正在将我的所有代码加载到 viewdidload() atm 没什么好说的了。只需将与可达性相关的代码从您的viewDidLoad 方法中移出,并将其放入viewDidAppear 方法中。 @rmaddy 谢谢它的工作! 【参考方案1】:

您必须将 AlertController 放在 ViewControllers 生命周期的 viewDidAppear 方法中,因为在 viewDidLoad 和 viewWillAppear 方法中,您当前的视图仍然不在窗口层次结构中。 如果你想展示更多的 ViewController,比如 AlertController,你需要一个完整加载的视图,你的新 ViewController 可以在其中呈现:

override func viewDidLoad() 
    super.viewDidLoad()
    //ViewControllers view not in the window hierarchy
    // Here you could make further initialization of your views subviews


override func viewWillAppear(_ animated: Bool) 
    //ViewControllers view ist still not in the window hierarchy
    //This is the right place to do for instance animations on your views subviews


override func viewDidAppear(_ animated: Bool) 
    // ViewControllers view ist fully loaded and could present further ViewController
    //Here you could do any other UI operations
    if Reachability.isConnectedToNetwork() == true
    
        print("Connected")
    
    else
    
        let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
        let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
        let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        controller.addAction(ok)
        controller.addAction(cancel)

        present(controller, animated: true, completion: nil)
    


这就是 Apple 文档中关于 ViewController 的说法: UIViewController 方法调用如下:

viewDidLoad()——当视图控制器的内容视图(顶部 它的视图层次结构)是从情节提要中创建和加载的。这 方法用于初始设置。但是,因为视图可能 由于应用程序中的资源有限而被清除,无法保证 它只会被调用一次。 viewWillAppear() - 适用于任何 您希望在视图变为之前始终发生的操作 可见的。因为视图的可见性可能会被 其他视图,此方法总是在紧接之前调用 内容视图出现在屏幕上。 viewDidAppear() - 适用于任何 您希望在视图变为时立即发生的操作 可见,例如获取数据或显示动画。因为一个 视图的可见性可能会被其他视图切换或遮挡,这 方法总是在内容视图出现后立即调用 在屏幕上。

参考:https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson4.html

【讨论】:

【参考方案2】:

这就是 Apple 文档中关于 ViewController 的说法:UIViewController 方法的调用如下:

viewDidLoad() - 在创建视图控制器的内容视图(其视图层次结构的顶部)并从情节提要加载时调用。此方法适用于初始设置。但是,由于应用中的资源有限,视图可能会被清除,因此无法保证只会调用一次。

viewWillAppear() - 适用于您希望始终在视图可见之前发生的任何操作。因为视图的可见性可能会被其他视图切换或遮挡,所以总是在内容视图出现在屏幕上之前立即调用此方法。

//viewDidAppear

    override func viewDidAppear(_ animated: Bool) 
    netTester()


//Internet Checker
func netTester() 

    reachability = Reachability.init()
    if ((self.reachability!.connection) != .none) 
        print("Internet is Ok")
     else
        print("Internet is nO ok")

        let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
        let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
        let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

        controller.addAction(ok)
        controller.addAction(cancel)

        present(controller, animated: true, completion: nil)
    

    do 
        try reachability!.startNotifier()
     catch 
        print("Unable to start notifier")
    

viewDidAppear() - 适用于您希望在视图可见时立即执行的任何操作,例如获取数据或显示动画。因为视图的可见性可能会被其他视图切换或遮蔽,所以总是在内容视图出现在屏幕上后立即调用此方法。

View Did Load - First 方法,当视图第一次加载但未出现在屏幕/窗口上时调用,仅加载。

仅在第一次加载视图时调用一次。

View Did Appear - 调用 viewWillAppear 后,将调用 viewDidAppear。这意味着视图现在出现在屏幕上。

用户从该视图控制器移动到另一个视图控制器并返回时调用的次数。

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621423-viewdidappear

【讨论】:

以上是关于检测 Internet 连接并显示 UIAlertview Swift 3的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序在后台运行时,iOS 会显示 UIAlert

在 UIAlert 视图中显示推送通知文本

无法使用 Reachability reachabilityForInternetConnection 检测 Internet 连接

我的蓝灯一直显示连接中,打不开网页,图标灰色,怎么办?

在不拍照的情况下检测微笑

Web Socket:无法在 Internet 断开连接时检测到客户端连接