我想侦测网络状态,当网络状态改变时,在当前控制器中显示错误视图。但是使用协议存在问题。 这是代码:
private func networkingDetection() {
//This is the detective method in appdelegate
try! reachability.startNotifier()
reachability.whenReachable = { [weak self] _ in
DispatchQueue.main.async {
self?.currentViewController().hideNetworkingErrorView()
}
}
reachability.whenUnreachable = { [weak self] _ in
DispatchQueue.main.async {
self?.currentViewController().showNetworkingErrorView()
}
}
}
这是协议
protocol NetworkingErrorProtocol {
// I want to show the default view if there is no networkingErrorView, and
when declare a custom view in controller, show the custom view.
//var networkingErrorView: UIView? { get }
func showNetworkingErrorView()
func hideNetworkingErrorView()
}
extension UIViewController: NetworkingErrorProtocol {
func showNetworkingErrorView() {
}
func hideNetworkingErrorView() {
}
}
任何人都可以告诉我如何解决这个问题?这真的让我发疯了。非常感谢。
答案 0 :(得分:0)
您的设置问题是,使UIViewController
符合您的协议不允许您在子类中接收该调用。如果您尝试覆盖子类中的协议函数,则会出现编译器错误:Declarations from extensions cannot be overridden yet
首先,关于NotificationCenter的说明。如果您需要应用程序的多个部分来通知更改,那将是一个很好的方法。如果您只需要告诉一个控制器,这是代表的经典用法。
以下是获得所需功能的两种方法:使用委托模式而不使用委托模式。
假设Manager
是监控发生的类:
使用委托模式
class Manager {
weak var networkDelegate : NetworkStatusListener?
func monitorNetworkStatus() {
var reachable = true;
if reachable {
// We can call the delegate directly
networkDelegate?.networkStatusChanged(.connected)
}
else {
networkDelegate?.networkStatusChanged(.disconnected)
}
}
}
没有委托模式的相同Manager。这对您当前的实施问题来说是最简单的解决方法。
class Manager {
func currentViewController() -> UIViewController { return vc }
func monitorNetworkStatus() {
var maybeAtListener = currentViewController()
// DON't SHIP THIS, but it can be helpful during development to make sure you didn't forget to conform one of your classes
assert(maybeAtListener is NetworkStatusListener, "Oops, did you mean to conform \(currentVC) to NetworkStatusListener")
var reachable = true;
if reachable {
// We can't be sure the controller conforms to the protocol but we can try
(maybeAtListener as? NetworkStatusListener)?.networkStatusChanged(.connected)
}
else {
(maybeAtListener as? NetworkStatusListener)?.networkStatusChanged(.connected)
}
}
}
然后是您的视图控制器
class MyController : UIViewController, NetworkStatusDelegate {
func networkStatusChanged(_ status: NetworkStatus) {
switch status {
case .connected:
// Normal UI
break
case .disconnected:
// No network connect
break;
}
}
}
此外,与您的问题没有直接关系,但对于此示例,我使用了稍微不同的协议设计方法,这对于“面向状态”的协议很有帮助。随着协议越来越大,拥有多个功能通常会变得更加乏味。
enum NetworkStatus {
case connected
case disconnected
}
protocol NetworkStatusListener : class {
func networkStatusChanged(_ status: NetworkStatus)
}
答案 1 :(得分:0)
尝试使用可访问性类的NSNotificationCenter
如果你想要整个应用程序,请在appdelegate的didFinishLaunchingWithOptions中添加
如果您希望在特定的Viewcontroller
中添加,请在您的特定viewcontroller中添加 NotificationCenter.default.addObserver(self, selector:Selector(("checkForReachability:")), name: NSNotification.Name.reachabilityChanged, object: nil);
let reachability: Reachability = Reachability.forInternetConnection();
reachability.startNotifier();
网络状态发生变化时调用此方法。
func checkForReachability(notification:NSNotification)
{
let networkReachability = notification.object as! Reachability;
_ = networkReachability.currentReachabilityStatus()
// do yor additional work here
}