如何在 Alamofire 中使用 NetworkReachabilityManager

Posted

技术标签:

【中文标题】如何在 Alamofire 中使用 NetworkReachabilityManager【英文标题】:How to use NetworkReachabilityManager in Alamofire 【发布时间】:2016-05-27 10:41:08 【问题描述】:

我想要类似于 Objective-C 中的 AFNetworking 的功能以及 Swift 中的 Alamofire NetworkReachabilityManager:

//Reachability detection
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) 
    switch (status) 
        case AFNetworkReachabilityStatusReachableViaWWAN: 
            [self LoadNoInternetView:NO];
            break;
        
        case AFNetworkReachabilityStatusReachableViaWiFi: 
            [self LoadNoInternetView:NO];
            break;
        
        case AFNetworkReachabilityStatusNotReachable: 
            break;
        
        default: 
            break;
        
    
];

我目前正在使用监听器来了解网络的状态变化

let net = NetworkReachabilityManager()
net?.startListening()

有人可以描述如何支持这些用例吗?

【问题讨论】:

【参考方案1】:

NetworkManager 类

class NetworkManager 

//shared instance
static let shared = NetworkManager()

let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.google.com")

func startNetworkReachabilityObserver() 

    reachabilityManager?.listener =  status in
        switch status 

            case .notReachable:
                print("The network is not reachable")

            case .unknown :
                print("It is unknown whether the network is reachable")

            case .reachable(.ethernetOrWiFi):
                print("The network is reachable over the WiFi connection")

            case .reachable(.wwan):
                print("The network is reachable over the WWAN connection")

            
        

        // start listening
        reachabilityManager?.startListening()
   

启动网络可达性观察者

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

        // add network reachability observer on app start
        NetworkManager.shared.startNetworkReachabilityObserver()

        return true
    

【讨论】:

reachabilityManager?.startListening() 你放错地方了兄弟。 :D 我试过了,但是当你关闭 wifi 时监听器会被调用一次,而当你打开它时不会再次被回调。当我在几个地方阅读时,我尝试引用它。例如,我尝试使用单例,但仍然遇到这种情况。 @JesusAdolfoRodriguez - 我在模拟器中测试我的应用程序时遇到了完全相同的问题,但是当我在设备上安装我的应用程序时,可达性管理器按照此处所写的方式工作。 @mattdedek 谢谢!我有同样的问题! 我们发现在某些带有代理服务器的企业网络下,对主机使用可达性会导致虚假无法访问。我不确切知道当时的网络是由第三方设置的,我们决定只是在没有主机的情况下启动它。【参考方案2】:

我自己找到了答案,即只需编写一个带有闭包的侦听器,如下所述:

let net = NetworkReachabilityManager()

net?.listener =  status in
    if net?.isReachable ?? false 

    switch status 

    case .reachable(.ethernetOrWiFi):
        print("The network is reachable over the WiFi connection")

    case .reachable(.wwan):
        print("The network is reachable over the WWAN connection")

    case .notReachable:
        print("The network is not reachable")

    case .unknown :
        print("It is unknown whether the network is reachable")

    


net?.startListening()

【讨论】:

你能进一步解释你的答案吗?我的意思是我应该在哪里添加这段代码我应该为这段代码创建单独的结构?【参考方案3】:

这是我的实现。我在单例中使用它。请记住保留可达性管理器参考。

let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.apple.com")

func listenForReachability() 
    self.reachabilityManager?.listener =  status in
        print("Network Status Changed: \(status)")
        switch status 
        case .NotReachable:
            //Show error state
        case .Reachable(_), .Unknown:
            //Hide error state
        
    

    self.reachabilityManager?.startListening()

【讨论】:

【参考方案4】:

SWIFT 5

网络状态结构

import Foundation
import Alamofire

struct NetworkState 

    var isInternetAvailable:Bool
    
        return NetworkReachabilityManager()!.isReachable
    

用途:-

  if (NetworkState().isInternetAvailable) 
        // Your code here
   

【讨论】:

这是否意味着我们不再需要使用reachabilityManager?.listener,因为它会给出错误Value of type 'NetworkReachabilityManager' has no member 'listener'【参考方案5】:

只要您保留对reachabilityManager 的引用,使用单例就可以工作

class NetworkStatus 
static let sharedInstance = NetworkStatus()

private init() 

let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.apple.com")

func startNetworkReachabilityObserver() 
    reachabilityManager?.listener =  status in

        switch status 

        case .notReachable:
            print("The network is not reachable")

        case .unknown :
            print("It is unknown whether the network is reachable")

        case .reachable(.ethernetOrWiFi):
            print("The network is reachable over the WiFi connection")

        case .reachable(.wwan):
            print("The network is reachable over the WWAN connection")

        
    
    reachabilityManager?.startListening()

所以你可以在你的应用中的任何地方这样使用它:

let networkStatus = NetworkStatus.sharedInstance

override func awakeFromNib() 
    super.awakeFromNib()
    networkStatus.startNetworkReachabilityObserver()

如果您的网络状态发生任何变化,您都会收到通知。 锦上添花this 是一个非常好的动画,可以显示您的互联网连接中断。

【讨论】:

【参考方案6】:

斯威夫特 5: 不需要监听器对象。只是我们需要调用闭包:

struct Network 

    let manager = Alamofire.NetworkReachabilityManager()

    func state() 
        manager?.startListening  status in
            switch status 
            case .notReachable :
                print("not reachable")
            case .reachable(.cellular) :
                print("cellular")
            case .reachable(.ethernetOrWiFi) :
                print("ethernetOrWiFi")
            default :
                print("unknown")
             
        
    

你可以像这样开始使用这个功能:

Network().state()

【讨论】:

【参考方案7】:

Apple 说尽可能使用结构而不是类。所以这是我的@rmooney 和@Ammad 的答案版本,但使用的是结构而不是类。此外,我没有使用方法或函数,而是使用计算属性,并且我从 @Abhimuralidharan 的这个 Medium post 中得到了这个想法。我只是把使用结构而不是类的想法(所以你不必有一个单例)和使用计算属性而不是方法调用放在一个解决方案中。

这是结构 NetworkState:

import Foundation
import Alamofire

struct NetworkState 

    var isConnected: Bool 
        // isReachable checks for wwan, ethernet, and wifi, if
        // you only want 1 or 2 of these, the change the .isReachable
        // at the end to one of the other options.
        return NetworkReachabilityManager(host: www.apple.com)!.isReachable
    

这是您在任何代码中使用它的方式:

if NetworkState().isConnected 
    // do your is Connected stuff here

【讨论】:

我必须在主机中提供“www.apple.com”吗?否则我可以给任何有效的主机吗? @user3182143 www.apple.com 只是一个例子,您应该输入您要检查的主机。在我自己的代码中,我将主机放置在我尝试运行的 API 所在的位置。【参考方案8】:

如下创建 NetworkManager 类对于 SWIFT 5

import UIKit
import Alamofire
class NetworkManager 
    static let shared = NetworkManager()
    let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.apple.com")
    func startNetworkReachabilityObserver() 
        reachabilityManager?.startListening(onUpdatePerforming:  status in

            switch status 
                            case .notReachable:
                                print("The network is not reachable")
                            case .unknown :
                                print("It is unknown whether the network is reachable")
                            case .reachable(.ethernetOrWiFi):
                                print("The network is reachable over the WiFi connection")
                            case .reachable(.cellular):
                                print("The network is reachable over the cellular connection")
                      
        )
    

而且用法会是这样的

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

        // add network reachability observer on app start
        NetworkManager.shared.startNetworkReachabilityObserver()

        return true
    

【讨论】:

- Alamofire (4.9.1): startListening 只是返回 bool 那是因为这个代码是为了兼容 Alamofire 5 而改变了这部分 API【参考方案9】:

Alamofire 5 及更高版本

import Alamofire

// MARK: NetworkReachability

final class NetworkReachability 
    
    static let shared = NetworkReachability()

    private let reachability = NetworkReachabilityManager(host: "www.apple.com")!

    typealias NetworkReachabilityStatus = NetworkReachabilityManager.NetworkReachabilityStatus

    private init() 
    
    /// Start observing reachability changes
    func startListening() 
        reachability.startListening  [weak self] status in
            switch status 
            case .notReachable:
                self?.updateReachabilityStatus(.notReachable)
            case .reachable(let connection):
                self?.updateReachabilityStatus(.reachable(connection))
            case .unknown:
                break
            
        
    
    
    /// Stop observing reachability changes
    func stopListening() 
        reachability.stopListening()
    
    
    
    /// Updated ReachabilityStatus status based on connectivity status
    ///
    /// - Parameter status: `NetworkReachabilityStatus` enum containing reachability status
    private func updateReachabilityStatus(_ status: NetworkReachabilityStatus) 
        switch status 
        case .notReachable:
            print("Internet not available")
        case .reachable(.ethernetOrWiFi), .reachable(.cellular):
            print("Internet available")
        case .unknown:
            break
        
    

    /// returns current reachability status
    var isReachable: Bool 
        return reachability.isReachable
    

    /// returns if connected via cellular
    var isConnectedViaCellular: Bool 
        return reachability.isReachableOnCellular
    

    /// returns if connected via cellular
    var isConnectedViaWiFi: Bool 
        return reachability.isReachableOnEthernetOrWiFi
    

    deinit 
        stopListening()
    

使用方法:

AppDelegate 呼叫NetworkReachability.shared.startListening() 以开始监听可达性变化

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 
            
    var window: UIWindow?
           
            
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
             
        NetworkReachability.shared.startListening()
        
        // window and rootviewcontroller setup code
        
        return true
    
        

   

【讨论】:

【参考方案10】:

swift 4* + swift 5* 和 Alamofire 4.5+ 的解决方案

创建来自AlamofireNetworkReachabilityManager 类和 配置checkNetwork()方法

import Alamofire

class Connectivity    
    class func checkNetwork() ->Bool 
        return NetworkReachabilityManager()!.isReachable
    

用法

switch Connectivity.checkNetwork() 
  case true:
      print("network available")
      //perform task
  case false:
      print("no network")

【讨论】:

【参考方案11】:

Alamofire 5 略有改进

class NetworkManager 

//shared instance
static let shared = NetworkManager()

let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.google.com")

func startNetworkReachabilityObserver() 
    
    reachabilityManager?.startListening  status in
        switch status 

        case .notReachable:
            print("The network is not reachable")

        case .unknown :
            print("It is unknown whether the network is reachable")

        case .reachable(.ethernetOrWiFi):
            print("The network is reachable over the WiFi connection")

        case .reachable(.cellular):
            print("The network is reachable over the cellular connection")

        
     
  

 

【讨论】:

以上是关于如何在 Alamofire 中使用 NetworkReachabilityManager的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Alamofire 中使用 UITextField?

如何在 Alamofire 中使用 NetworkReachabilityManager

如何使用 Swift 5 在 Xcode 10.2.1 中添加 alamofire

如何在 Alamofire 中使用 PUT 请求

如何在swift中使用alamofire上传图库图片

如何使用 alamofire 将服务的响应存储在模型中