Swift 3: 检查网络连接(重复出现)viewDidAppear未显示

8

好的,我对Swift还比较新,对于我正在尝试做什么或者是否走了错误的方向有些困惑。(https://github.com/ashleymills/Reachability.swift

这是我的viewDidLoad方法:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    checkConnection()

}

我接着使用了来自Reachability GitHub项目的函数代码:

func checkConnection() {
    //declare this property where it won't go out of scope relative to your listener
    let reachability = Reachability()!

    reachability.whenReachable = { reachability in
        // this is called on a background thread, but UI updates must
        // be on the main thread, like this:
        DispatchQueue.main.async {
            if reachability.isReachableViaWiFi {
                print("Reachable via WiFi")
            } else {
                print("Reachable via Cellular")
            }
        }
    }
    reachability.whenUnreachable = { reachability in
        // this is called on a background thread, but UI updates must
        // be on the main thread, like this:
        DispatchQueue.main.async {

            self.dim(direction: .In, alpha: self.dimLevel, speed: self.dimSpeed)
            self.performSegue(withIdentifier: "mainToAlertNoInternet", sender:  self)
        }
    }

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

如您所见,当没有互联网时,这是代码:
self.dim(direction: .In, alpha: self.dimLevel, speed: self.dimSpeed)
            self.performSegue(withIdentifier: "mainToAlertNoInternet", sender:  self)

该 Dim 功能来自 (http://www.totem.training/swift-ios-tips-tricks-tutorials-blog/ux-chops-dim-the-lights) 。mainToAlertNoInternet 加载下一个视图并以透明方式覆盖当前视图,形成警告样式。

所以,第二个 segue 包含一个视图和一个按钮。当没有网络连接时加载这个视图,没有什么特别的:

enter image description here

“重试”按钮链接到 Segue 的 Exit 并在第一个视图控制器中运行此函数:

@IBAction func unwindFromSecondary(segue: UIStoryboardSegue) {
    dim(direction: .Out, speed: dimSpeed)
    checkInternetConnection()
}

我添加了一个名为mainToAlertNoInternet的函数,这样当用户点击“再试一次”时,它将返回到第一个segue并重新运行测试。然而,当我点击“再试一次”时,我会收到以下错误信息:

警告:尝试在未显示其视图层次结构的上呈现 !

希望我已经解释清楚了我所设置的内容。现在是问题:

1)我该如何修复此错误? 2)我这样做的方式正确吗?还是有更好的方法?

这是我的需求:

我想在应用程序加载时立即检查互联网连接。如果没有连接,我想像以前一样显示segue。如果用户点击“再试一次”,我希望它返回到第一个控制器并重新运行检查,如果仍然没有连接,则再次像最初那样显示segue。我希望这是一个重复的过程,直到有互联网连接。

感谢您的帮助。提前致谢。

编辑:

我已经在ViewDidAppear方法中添加了函数调用,如下所示:

override func viewDidAppear(_ animated: Bool) {
    checkInternetConnection()
}

然而,它并没有运行。当我这样做时,unwindFromSecondary 函数中的 DIM 也没有被调用。

编辑2:

刚刚在我的 viewDidAppear 中添加了这一行:

print("Appeared")

这个函数最初会被调用一次,但之后不再调用。

问题:

在 unwindSegue 后,如何让一个函数在所有内容重新加载后只运行一次?

有什么想法吗?

更新3

好的,我已经查看了下面的答案:

@MarkP 的答案很好。谢谢你 然而,@iSee 的答案让我想到,也许我应该换一种方式来做这件事。

我在这篇文章中添加了一个赏金,希望能得到一个详细的答案,可以向我展示并解释如何实现以下内容:

在我的应用程序中,我需要确保在任何加载视图时都保持互联网连接存在(可能是一个计时器)。我希望像当前的方式一样,如果没有互联网,它将弹出具有此 segue 的 ViewController:

performSegue(withIdentifier: "mainToAlertNoInernet", sender: self)

看起来App Delegate是合适的位置,但我不确定如何实现。

我是iOS开发的新手,因此希望能得到一些解释和指导。

感谢您的时间。非常感激。


可能是重复的问题,参考 whose view is not in the window hierarchy - Daniel Storm
3个回答

3

我猜测您对iOS开发完全不了解。

  1. 这个警告与您的互联网连接代码无关。

  2. 您收到的警告不是错误。它只是一个警告。

  3. 出现这种情况的原因在于这篇文章这篇文章中有很好的解释。
  4. 要想摆脱这个警告,您应该不要从viewDidLoad调用performSegue(有关详细信息,请参见上面的链接)。
  5. 为了执行网络检查,最好使用AppDelegate(可以更好地控制应用程序的流程)。

祝一切顺利 :)

编辑:请参考此处链接以获取更多信息。我可以轻松地在此重新发布,但由于已经回答,您可以参考上面的链接了解原因并避免出现这种情况。


是的,你说得对,我对iOS开发整体都很新。你认为你能不能再具体一些,告诉我需要做什么? - JamesG

2
正如@iSee所指出的链接一样,这是因为视图还没有添加到视图层次结构中,所以你无法移动到它。因此需要使用self.dismissViewControllerAnimated
@IBAction func unwindFromSecondary(segue: UIStoryboardSegue) {
    dim(direction: .Out, speed: dimSpeed)
    self.dismiss(animated: true) {
        self.checkInternetConnection()
    }

}

0

我在应用程序委托中使用这个 ->

 func reachablityCode() {
        AFNetworkReachabilityManager.sharedManager()
        AFNetworkReachabilityManager.sharedManager().startMonitoring()
        AFNetworkReachabilityManager.sharedManager().setReachabilityStatusChangeBlock({(status) in
            let defaults = NSUserDefaults.standardUserDefaults()
            if status == .NotReachable {
                defaults.setBool(false, forKey:REACHABLE_KEY)
            }
            else {
                defaults.setBool(false, forKey: REACHABLE_KEY)
            }
            defaults.synchronize()
        })
    }

然后在基础文件中添加如下内容 ->

 func isReachable() -> Bool {
        return NSUserDefaults.standardUserDefaults().boolForKey(REACHABLE_KEY)
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接