Swift 中的 AFNetworking 可达性管理器

Posted

技术标签:

【中文标题】Swift 中的 AFNetworking 可达性管理器【英文标题】:AFNetworking Reachability Manager in Swift 【发布时间】:2016-05-11 07:05:19 【问题描述】:

在 Swift 中有没有办法让AFNetworking Reachability 每秒不断检查互联网连接,到目前为止,这就是我所拥有的,它只检查一次:

override func viewDidLoad() 
AFNetworkReachabilityManager.sharedManager().startMonitoring()
        AFNetworkReachabilityManager.sharedManager().setReachabilityStatusChangeBlock(status: AFNetworkReachabilityStatus?) in
            switch status!.hashValue 
            case AFNetworkReachabilityStatus.NotReachable.hashValue:

                print("no internet")
            case AFNetworkReachabilityStatus.ReachableViaWiFi.hashValue,AFNetworkReachabilityStatus.ReachableViaWWAN.hashValue:

                print("with internet")

            default:
                print("unknown")
            
        

如何连续检查网络连接?

【问题讨论】:

当您调用 API 时检查互联网连接,而您不需要。 可以添加观察者。 @RichardG - 我添加了一个观察者,但我没有包括在那里,但它仍然只检查一次。 是的,它一次只检查一次,这就是你在 viewdidload 中调用的原因, @Anbu.Karthik - 我应该怎么做才能持续检查互联网? 【参考方案1】:

AFNetworking 可达性确实持续检查连接,如果我的一些应用程序运行良好,我会使用它。如果您的代码不起作用,我相信可能是因为您在使用setReachabilityStatusChangeBlock 设置处理程序之前调用了startMonitoring,因此您可能会错过初始事件。此外,与您的问题无关,但您可以进行改进,您不需要在 switch 语句中使用hashValue,您可以直接使用status,并且您会受益于 Swift 编译器检查完成的case 语句。总之,试试你的代码的以下版本,看看它是否有效:

    AFNetworkReachabilityManager.sharedManager().setReachabilityStatusChangeBlock  (status: AFNetworkReachabilityStatus) -> Void in
        switch status 
        case .NotReachable:
            print("Not reachable")
        case .ReachableViaWiFi, .ReachableViaWWAN:
            print("Reachable")
        case .Unknown:
            print("Unknown")
        

    
    AFNetworkReachabilityManager.sharedManager().startMonitoring()

【讨论】:

它仍然在检查一次。我把它放在 appDelegate didFinishLaunchingWithOptions @SydneyLoteria 太奇怪了,它对你不起作用……通过在didFinishLaunchingWithOptions 中设置它也对我有用,这是我刚刚制作的一个小项目,您可以查看:@ 987654321@ @SydneyLoteria 现在我认为您希望它有意检查每一秒而不是每次状态变化(即从连接 -> 无连接)?所以你想要的是,如果总是有连接,每秒打印一次:“with internet”,“with internet”,......?它只是不能那样工作,只有当状态改变时你才会收到通知。而且我认为您不需要它那样做,只需存储最后通知的状态并在需要时检查它。【参考方案2】:

您不应每分钟或定期检查可重复性。这不是好的做法,它会降低应用程序的性能。

您可以获得可重复性更改通知。所以当rechabilty改变时你可以执行一些任务

你可以这样做,

您必须先创建一个Reachability 对象,然后才能接收来自它的通知。此外,请务必在您创建的Reachability 对象上调用startNotifier() 方法。这将是如何在您的应用程序委托中执行此操作的示例:

 class AppDelegate: UIResponder, UIApplicationDelegate

private var reachability:Reachability!;

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool

    NSNotificationCenter.defaultCenter().addObserver(self, selector:"checkForReachability:", name: kReachabilityChangedNotification, object: nil);

    self.reachability = Reachability.reachabilityForInternetConnection();
    self.reachability.startNotifier();


func checkForReachability(notification:NSNotification)

    // Remove the next two lines of code. You cannot instantiate the object
    // you want to receive notifications from inside of the notification
    // handler that is meant for the notifications it emits.

    //var networkReachability = Reachability.reachabilityForInternetConnection()
    //networkReachability.startNotifier()

    let networkReachability = notification.object as Reachability;
    var remoteHostStatus = networkReachability.currentReachabilityStatus()

    if (remoteHostStatus.value == NotReachable.value)
    
        println("Not Reachable")
    
    else if (remoteHostStatus.value == ReachableViaWiFi.value)
    
        println("Reachable via Wifi")
    
    else
    
        println("Reachable")
    


您可以从Apple Documentation下载可达性类

希望这会有所帮助:)

【讨论】:

【参考方案3】:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

// internetReachable is declared as property.
internetReachable = [Reachability reachabilityForInternetConnection];
[internetReachable startNotifier];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:)  name:kReachabilityChangedNotification object:nil];



- (void)checkNetworkStatus:(NSNotification *)notice 
// called when network status is changed

NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)

    case NotReachable:
    
        NSLog(@"The internet is down.");
        break;
    
    case ReachableViaWiFi:
    
         NSLog(@"The internet is Connected.");
        break;
    
    case ReachableViaWWAN:
    
        NSLog(@"The internet is working via WWAN!");
        break;
    

    


//#import "Reachability.m"

static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)

#pragma unused (target, flags)
NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");

Reachability* noteObject = (__bridge Reachability *)info;
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];

【讨论】:

【参考方案4】:

您可以使用 - https://github.com/ashleymills/Reachability.swift

//declare this inside of viewWillAppear
do 
    reachability = try Reachability.reachabilityForInternetConnection()
 catch 
    print("Unable to create Reachability")
    return


NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:",name: ReachabilityChangedNotification,object: reachability)
do
    try reachability?.startNotifier()
    catch
        print("could not start reachability notifier")
    

//declare this inside of viewWillDisappear
reachability!.stopNotifier()
NSNotificationCenter.defaultCenter().removeObserver(self,
        name: ReachabilityChangedNotification,
        object: reachability)


func reachabilityChanged(note: NSNotification) 

    let reachability = note.object as! Reachability

    if reachability.isReachable() 

        print("NETWORK REACHABLE.")
     
    if reachability.isReachableViaWiFi()
    
        print("NETWORK REACHABLE VIA WIFI.")
    
    if reachability.isReachableViaWWAN()
    
        print("NETWORK REACHABLE VIA WWAN.")
    
    else 
        print("NETWORK NOT REACHABLE.")

    

【讨论】:

【参考方案5】:

也用于我自己的存档目的。您可以在他/她的回答中将其用作@Lion。

只需在 AppDelegate.swift 中的 didFinishLaunchingWithOptions 中调用 Reachability.registerListener()。它会自动通知您更改。

//
//  CheckInternet.swift
//
//  Created by Dincer on 14/11/15.
//

import AFNetworking

public class Reachability 
    private static let theSharedInstance:Reachability = Reachability();
    private var isClientOnline:Bool = true;
    private var isClientWiFi:Bool = false;
    private var isClientConnectionUnknown = false;

    func onOnline() 
        print("****************************************** Network goes online.");
    

    func onOffline() 
        print("****************************************** Network goes offline.");
    

    func onWiFi() 
        print("****************************************** Wifi network on");
    

    func onGSM() 
        print("****************************************** GSM network on");
    

    func onUnknownConnectionStatus() 
        print("****************************************** Unkown network status");
    

    func isConnectedToNetwork() -> Bool 
        return isClientOnline;
    

    func isConnectedToWiFi() -> Bool 
        return isClientOnline && isClientWiFi;
    

    static func sharedInstance() -> Reachability 
        return Reachability.theSharedInstance;
    

    static func registerListener() 
        sharedInstance().registerListener();
    

    func registerListener() 
        AFNetworkReachabilityManager.sharedManager().setReachabilityStatusChangeBlock  (status: AFNetworkReachabilityStatus) -> Void in
            switch status 
                case .NotReachable:
                    self.isClientConnectionUnknown = false;

                    if self.isClientOnline 
                        self.isClientOnline = false;
                        self.onOffline();
                    
                case .ReachableViaWiFi:
                    self.isClientConnectionUnknown = false;

                    if !self.isClientOnline 
                        self.isClientOnline = true;
                        self.onOnline();
                    

                    if !self.isClientWiFi 
                        self.isClientWiFi = true;
                        self.onWiFi();
                    
                case .ReachableViaWWAN:
                    self.isClientConnectionUnknown = false;

                    if !self.isClientOnline 
                        self.isClientOnline = true;
                        self.onOnline();
                    

                    if self.isClientWiFi 
                        self.isClientWiFi = false;
                        self.onGSM();
                    
                case .Unknown:
                    if !self.isClientConnectionUnknown 
                        self.isClientConnectionUnknown = true;
                        self.onUnknownConnectionStatus();
                    
            
        

        AFNetworkReachabilityManager.sharedManager().startMonitoring();
    


【讨论】:

以上是关于Swift 中的 AFNetworking 可达性管理器的主要内容,如果未能解决你的问题,请参考以下文章

防止在首次启动 iOS 时调用 AFNetworking 可达性状态

AFNetworking - 可达性总是返回 -1

AFNetworking 可达性状态不变

AFNetworking 2.0 可达性不起作用

AFNetworking - 检查域的可达性

AFNetworking 可达性ForLocalWiFi