在后台检查网络连接并上传数据

时间:2015-09-04 08:23:54

标签: ios

我要求能够检查是否有失败状态的数据并通过webservice上传。

流程将是:

  
      
  1. 用户尝试上传数据但由于没有互联网连接而失败
  2.   
  3. 用户停止使用应用,因此应用程序变为背景
  4.   
  5. 应用程序开始确定是否可以使用互联网连接
  6.   
  7. 如果可用,它会直接调用Web服务上传数据
  8.   
  9. 如果没有,则返回#3
  10.   

回到我上一次开发< iOS 7,之前的背景时间是10分钟,但变成了3分钟。

后台抓取

  

调用此方法时,您的应用最长可达30秒   挂钟时间执行下载操作并调用   指定的完成处理程序块在实践中,您的应用应该致电   下载后尽快完成处理程序块   需要的数据。如果你没有及时调用完成处理程序,那么你的   应用已终止。

此外,这些是唯一允许执行背景的应用程序:

  
      
  1. 在后台播放用户可听内容的应用,例如音乐播放器应用
  2.   
  3. 在后台录制音频内容的应用。
  4.   
  5. 随时向用户通知其位置信息的应用,例如导航应用
  6.   
  7. 支持互联网协议语音(VoIP)的应用
  8.   
  9. 需要定期下载和处理新内容的应用(后台提取)
  10.   
  11. 从外部附件接收定期更新的应用
  12.   

我还没有办法在iOS上做背景,或者至少我可以在后台获得网络状态吗?

注意:我的应用仅供内部发布,无需担心拒绝。

1 个答案:

答案 0 :(得分:2)

您需要做的是使用NSURLSession代替NSURLConnection(如果您仍在使用它)

NSURLSession和NSURLConnection之间的区别

  • NSURLConnection:如果我们与NSURLConnection打开连接并且系统中断我们的应用程序,当我们的应用程序进入后台模式时,我们收到或发送的所有内容都将丢失。 Process diagram with NSURLConnection

  • NSURLSession:解决了这个问题,也让我们没有进程下载。即使我们无法访问,它也会管理连接过程。您需要在AppDelegate中使用application:handleEventsForBackgroundURLSession:completionHandler Process diagram with NSURLSession

  

因此,使用NSURLSession,您不需要管理或检查   您的互联网连接,因为操作系统为您完成。

额外:如何在我的iOS应用中检查互联网连接

  

免责声明:我不确定以下框架是否可以在后台模式下运行

您可以使用框架可移植性来检查您的设备是否具有互联网连接。

https://github.com/tonymillion/Reachability

它是Apple的Reachability类的直接替代品,它支持在您收到更改可达性的NSNotification时执行操作的块。

您可以在他的回购中查看README.md,但使用起来非常简单。

使用NSNotification

<强> 1

AppDelegate 中,您必须致电

[Reachability reachabilityWithHostname:@"www.google.com"];

此外,您需要声明一个属性来存储该值

@property (strong, nonatomic) Reachability *reach;     

所以现在您必须将以下代码放在application:didFinishLaunchingWithOptions:

_reach = [Reachability reachabilityWithHostname:@"www.google.com"];

<强> 2

在Controller中,您需要检查是否可达状态,您必须订阅该通知

[[NSNotificationCenter defaultCenter] addObserver:_sharedInstance selector:@selector(reachabilityDidChange:) name:@"kReachabilityChanged" object:nil];

<强> 3

现在,您可以实现选择器reachabilityDidChange:,检查现在是否已连接。把它放在同一个控制器中。

- (void)reachabilityDidChange:(NSNotification *)note
{
    Reachability * reach = (Reachability *)[note object];

    if (self.appDelegate.wasConnected != [reach isReachable]){
        if ([reach isReachable]){
            NSLog(@"Notification Says Reachable");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"ConnectionIsReachable" object:nil];
            [self sendPendingOperations];

        }else{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"ConnectionIsUnreachable" object:nil];
            NSLog(@"Notification Says Unreachable");
        }

        self.appDelegate.wasConnected = [reach isReachable];
    }
}

As you can see, we store the last connection state also in a AppDelegate property

`@property BOOL wasConnected;`

<强> 4

现在您必须订阅这些新通知(ConnectionIsReachableConnectionIsUnreachable)并执行您需要执行的操作。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showNoConnectionAlert) name:@"ConnectionIsUnreachable" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideNoConnectionAlert) name:@"ConnectionIsReachable" object:nil];

使用块

我没有对它进行测试,但我将官方文档复制给您

// Allocate a reachability object
Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"];

// Set the blocks
reach.reachableBlock = ^(Reachability*reach)
{
    // keep in mind this is called on a background thread
    // and if you are updating the UI it needs to happen
    // on the main thread, like this:

    dispatch_async(dispatch_get_main_queue(), ^{
      NSLog(@"REACHABLE!");
    });
};

reach.unreachableBlock = ^(Reachability*reach)
{
    NSLog(@"UNREACHABLE!");
};

// Start the notifier, which will cause the reachability object to retain itself!
[reach startNotifier];