如何在iOS中在后台接收可达性通知当Wi-Fi网络断开时?

24

我已经成功使用Reachability来检测网络状态并在发生更改时接收通知(例如:iOS 4下Reachability指南)。

我的问题不是如何启动和运行Reachability,而是以下内容:

我的AppDelegate处理Reachability相关事宜。当应用程序正在运行或处于后台(applicationDidEnterBackground:)时,应用程序会收到通知(kReachabilityChangedNotification)。

该应用程序旨在在意识到失去Wi-Fi连接(例如测试时在设置中切换Wi-Fi),重新加载播放音频流。在实际测试中,当我离开访问点的范围时,经常失去Wi-Fi连接。我发现在这种情况下,Reachability并没有太大帮助。我不确定是因为当屏幕锁定时无法接收Reachability通知,还是Reachability无法处理从越来越远的Wi-Fi访问点慢慢减弱的信号,但无论如何,我都无法弄清楚为什么实际测试与理想化的情况不符。

这是我的代码样式。首先,我设置接收通知并开始监听Reachability:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // check for internet connection
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(checkNetworkStatus:) 
                                                 name:kReachabilityChangedNotification object:nil];

    // Set up Reachability
    internetReachable = [[Reachability reachabilityForInternetConnection] retain];
    [internetReachable startNotifier];    

    ....

    return YES;
}

然后,这是响应连接变化的函数:

- (void)checkNetworkStatus:(NSNotification *)notice {
    // called after network status changes

    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
    switch (internetStatus)
    {
        case NotReachable:
        {
            NSLog(@"The internet is down.");
            break;
        }
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI");
            break;            
        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN!");
            break;            
        }
    }    
}

即使应用程序在后台运行,通知也会通过,但在上述的现实世界测试中没有收到。

感谢任何帮助。


你尝试过使用 reachabilityForInternetConnectionreachabilityForLocalWifi 的组合吗? - Art Gillespie
你找到解决方法了吗?我遇到了类似的问题,这里的解决方案似乎没有帮助或不是我要找的。 - newenglander
我不知道我是否解决了我的具体问题,因为我最近没有需要在那个项目上工作。你是否按照@Hurden的建议确保应用程序正在后台运行,并使用后台任务? - Tim Arnold
1
是的,那确实是解决方案,不过稍微有点变化。如果有人遇到相同的问题,我会添加另一个答案。 - newenglander
2个回答

5

默认情况下,应用程序在后台状态下只能停留很短的时间,大多数应用程序很快就会进入挂起状态。这意味着应用程序处于后台,但不执行代码。因此,您自定义实现的通知不起作用。 必须在应用委托方法中的唤醒时间重新查询NetworkReachability:

applicationWillEnterForeground:
applicationDidBecomeActive 

1
我正在开发一个VoIP应用程序,该应用程序在iPhone启动时在后台启动,此时可能无法连接到网络(例如,如果手机具有密码和/或带有PIN码的SIM卡)。但是,由于应用程序直接在后台启动,因此不会调用委托方法applicationDidEnterBackground:。相反,我直接在application:didFinishLaunchingWithOptions中使用@Hurden的想法,检查applicationState以查看应用程序是否实际上在后台启动。这使我的应用程序在手机解锁后(使用存储的密码连接WiFi)能够获得kReachabilityChangedNotification通知。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接