可达性 - 显示webView之前的最佳实践

时间:2009-08-17 20:34:07

标签: iphone

我想在我的应用程序中显示webView之前/之后检查“可达性”。

到目前为止,我已经包含了reachbility.h / .m文件,并将SystemConfiguration.framework添加到项目中。

这就是我在互联网上找到的协议的终点,来自所有帖子和博客等等。每个人对此之后要做的事情有不同的想法/意见。另外,我发现很多部分代码片段并不是真正完整的解决方案,可调用的方法等等。如何使用它们等。

我还发现有人警告你应该在检查可达性之前尝试重新连接......但我还没有找到共识或完整的解决方案。我的应用程序似乎重新连接到wifi而没有任何额外的代码...所以我也很困惑这里......

任何有助于清除泥泞水域的帮助都将受到赞赏。我只是在寻找一个简单直接的解决方案。

接受的答案:我想向可能稍后阅读此问题的新手注意......您将要执行以下操作:

将此添加到.h文件中:

- (BOOL) connectedToNetwork: (NSString *) remoteServer;
- (void) appLoadError: (NSString *) altertTitle alertMessage: (NSString *) altertMsg;

您需要在.m文件的顶部导入这些内容:

  

SYS / socket.h中

     

netinet / in.h中

     

netinet6 / in6.h

     

ARPA / inet.h

     

ifaddrs.h

     

netdb.h中

     

SystemConfiguration / SystemConfiguration.h

如果错误,请纠正我......对我来说似乎工作正常......

2 个答案:

答案 0 :(得分:2)

当我需要访问Internet时,我一直在我的App Delegate中使用此方法。我随着时间的推移调整了它的不同访问类型,它对我很有帮助。它是Google快速搜索此主题后可以找到的众多方法之一的变体。

围绕这个提出一个硬性和快速的策略是一个棘手的事情。平台本身提供不同的连接选项,根据每个特定应用程序的需要有利有弊。我在下面使用的方法只是一般连接测试,这意味着设备可以通过某种连接机制到达Internet。

- (BOOL) connectedToNetwork: (NSString *) remoteServer {
    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;

    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);

    if (!didRetrieveFlags){
        NSLog(@"Error. Could not recover network reachability flags");
        return NO;
    }

    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;

    NSURL *testURL = [NSURL URLWithString: remoteServer];
    NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL  cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
    NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];

    return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}

我通常在applicationDidFinishLaunching中调用它。如果检查返回false,我通常会生成错误消息(见下文)。这是因为Apple禁止通过设备上的主页按钮以外的任何方式退出应用程序。

...
else if(![self connectedToNetwork: [NSString stringWithFormat: @"http://%@:%@/", sharedSettings.server, sharedSettings.port]]){
        [self appLoadError: @"No Internet Detected" alertMessage:@"This application requires an active Internet connection.  No content is available."];        
}
...
- (void) appLoadError: (NSString *) altertTitle alertMessage: (NSString *) altertMsg {
    UIAlertView *loadErr = [[UIAlertView alloc] initWithTitle: altertTitle message: altertMsg delegate: self cancelButtonTitle: @"OK" otherButtonTitles: nil];
    [loadErr show];
    [loadErr release];

    // Load static screen
    UIImage *image = [UIImage imageNamed:@"Error_NoInternet.png"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

    [controller setNavigationBarHidden: YES animated: NO];

    [window addSubview: imageView];
    [imageView release];
}

答案 1 :(得分:0)

请注意,我认为该方法在每次调用时都会泄漏NSURLConnection(在底部testConnection)。

您可能想要使用

+ (NSURLConnection *)connectionWithRequest:
        (NSURLRequest *)request delegate:(id)delegate

代替。