【问题标题】:Run Internet Connection Check Throughout Entire App在整个应用程序中运行 Internet 连接检查
【发布时间】:2013-03-03 00:57:52
【问题描述】:

以下方法非常适用于检查用户是否有互联网连接。我想检查整个应用程序中的互联网连接,并且想知道是否可以将它放在我的 App Delegate 中的某个地方,它会被每个视图控制器调用。

有没有办法做到这一点?如果我把它放在我的 applicationDidFinishLaunching 中,它似乎无法正常工作。任何建议都会很棒!谢谢!

NSURL *scriptUrl = [NSURL URLWithString:@"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data) {
    NSLog(@"Device is connected to the internet");
}
else {
    NSLog(@"Device is not connected to the internet");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Internet Connectivity" 
    message:@"You must have an internet connection" delegate:self cancelButtonTitle:@"OK" 
    otherButtonTitles:nil, nil];
    [alert show];
    return;
}

【问题讨论】:

    标签: iphone ios objective-c xcode


    【解决方案1】:

    如果您希望将此特定方法放置在可以从整个应用程序访问和调用的位置,那么这只是一个设计决策。有很多方法可以实现这一点。

    我喜欢在实现全局方法时使用单例范式。约翰华兹华斯在一篇简洁的博文中对此进行了介绍:

    http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/

    下面是一小段代码:

    InternetConnectionChecker.h

    #import <Foundation/Foundation.h>
    
    @interface InternetConnectionChecker : NSObject
    
    // Accessor for singelton instance of internet connection checker.
    + (InternetConnectionChecker *)sharedInternetConnectionChecker;
    
    // Check to see whether we have a connection to the internet. Returns YES or NO.
    - (BOOL)connected;
    
    @end
    

    InternetConnectionChecker.m

    #import "InternetConnectionChecker.h"
    
    @implementation InternetConnectionChecker
    
    // Accessor for singelton instance of internet connection checker.
    + (InternetConnectionChecker *)sharedInternetConnectionChecker
    {
        static InternetConnectionChecker *sharedInternetConnectionChecker;
        @synchronized(self)
        {
            if (!sharedInternetConnectionChecker) {
                sharedInternetConnectionChecker = [[InternetConnectionChecker alloc] init];
            }
        }
        return sharedInternetConnectionChecker;
    }
    
    // Check to see whether we have a connection to the internet. Returns YES or NO.
    - (BOOL)connected
    {
        NSURL *scriptUrl = [NSURL URLWithString:@"http://www.google.com/m"];
        NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
        if (data) {
            NSLog(@"Device is connected to the internet");
            return TRUE;
        }
        else {
            NSLog(@"Device is not connected to the internet");
            return FALSE;
        }
    }
    
    @end
    

    在我的示例中,我修改了您的方法以返回 true/false,以便您可以在 UI 中适当地处理调用该方法的结果,但如果您愿意,您可以继续显示 UIAlertView。

    然后您可以通过以下方式使用单例:

    InternetConnectionChecker *checker = [InternetConnectionChecker sharedInternetConnectionChecker];
    BOOL connected = [checker connected];
    

    【讨论】:

    • 谢谢艾略特!这太棒了!所以在我的视图控制器中,我需要做#import“InternetConnectionChecker.h”吗?将这一切整合在一起的 viewController 会是什么样子?
    • 完全正确。导入后两行:InternetConnectionChecker *checker = [InternetConnectionChecker sharedInternetConnectionChecker]; BOOL connected = [checker connected]; 应该足以调用您的方法。
    • 太好了,如果 (connected == TRUE) { ... } yes?
    【解决方案2】:

    当然有更复杂的方法,但最简单的方法(也是我使用的方法)是简单地创建一个“CheckNetwork”类,将您的方法作为返回布尔值的类方法,即:

    + (BOOL) checkConnection{
       yourMethodDetails;
    }
    

    然后只需将#import "CheckNetwork.h" 导入项目中的任何文件并调用

    if([CheckNetwork checkConnection]){
        whatever you want to do here;
    }
    

    【讨论】:

      【解决方案3】:

      虽然单例类和静态方法是一种方式,但您也可以在 .h 文件中实现静态内联方法,而不是 .m 文件

      此外,作为旁白,使用 NSURL 和 google.com 来检查互联网连接不是一个好习惯。

      因为,

      • 不是简单的ping操作
      • 它会下载整个页面,这可能会耗费时间
      • OS 提供的方式更加激进和恰当。

      如果您正在使用特定网站,那么使用该网站进行连接是最佳实践,我认为。参见Jon Skeetthis Answer

      我建议使用 Apple 的 Reachability 框架。

      或者如果您需要更紧凑的单功能版本,您也可以使用自己摘录自Reachabilty的这个功能

      + (BOOL) reachabilityForInternetConnection;
      {
          struct sockaddr_in zeroAddress;
          bzero(&zeroAddress, sizeof(zeroAddress));
          zeroAddress.sin_len = sizeof(zeroAddress);
          zeroAddress.sin_family = AF_INET;
      
          SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
      
          SCNetworkReachabilityFlags flags;
          if (SCNetworkReachabilityGetFlags(reachability, &flags))
          {
              return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
          }
          return NO;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多