检测Internet连接并显示UIAlertview Swift 3

kil*_*urn 2 uialertview reachability ios swift3 xcode8

我正在创建一个应用程序,通过使用if else语句检测是否存在与Internet的连接,当有互联网时,除了没有互联网连接之外什么也不做,然后提醒视图说应用程序需要互联网我管理发现可达性但是在我的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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我的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()
        //...
    }
Run Code Online (Sandbox Code Playgroud)

并且看起来警报视图没有弹出任何建议?或者帮忙?谢谢

wei*_*a19 6

您必须将AlertController放在ViewControllers生命周期的viewDidAppear方法中,因为在方法viewDidLoad和viewWillAppear中,您当前的视图仍然不在窗口层次结构中.
如果您想要提供更多ViewControllers,例如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)
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

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