【问题标题】:Data not sent from a background via 3G不是通过 3G 从后台发送的数据
【发布时间】:2016-11-08 13:07:45
【问题描述】:

我有一个应用程序在后台运行时向服务器发送数据。下面是负责数据发送的代码:

-(bool) sendStats: (MCStatsSender*) val{

    if(![self checkInternet]){ //Using Reachability here

        return false;
    }

    NSDictionary *inputData = [NSDictionary dictionaryWithObjectsAndKeys:
                               self.propertyA.value, "key1",
                               val.data, "key2",
                               nil];


    [myNetworkManager doRequest:[myRequestManager createWithStringAndDictionary:MY_URL Data:inputData handler:myHandler user:val]];
    return true;
}

所以inputData 是一个带有字符串的简单字典。

doRequest 方法基于 NSURLSession,基本上如下所示:

-(void) doRequest: (MCRequest*) request{

    [tasks addObject:request];

    if(m_session == nil){
        NSURLSessionConfiguration* config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"key-%lu",reqid]];
        m_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
    }

    NSURLSessionDataTask* task = [m_session dataTaskWithRequest:request.generatedRequest];
    request.reqId = task.taskIdentifier;
    [task resume];  
}

正如我所说,一切都通过 Wi-Fi 运行,应用程序进入后台,几分钟后,自定义蓝牙设备发送一些数据并将应用程序从暂停模式中唤醒。 iOS 应用程序接收到数据后,如果设备通过 3G 连接,则无法将其发送到服务器。我很肯定收到通过蓝牙发送的数据,因为它存储在本地数据库中。

还有一个重要的事实。如果应用程序通过 Xcode 运行,即使设备通过 3G 连接,应用程序也会从后台发送数据。为此,我运行一个应用程序,然后点击主页按钮将其置于后台。

不知道有什么区别,为什么应用程序通过电缆连接到 Mac 时的行为会有所不同,以及为什么不通过 3G(甚至 2G)发送数据?

附加信息:

我不是在尝试上传文件,而是只是将 JSON 发送到服务器。

【问题讨论】:

  • 在您的设备中获得蓝牙数据多长时间后??
  • @CodeChanger 应用每五分钟或更短时间从蓝牙获取数据。我确定收到了来自蓝牙的数据,因为我将其存储在本地 sqlite 数据库中。
  • 好的,据我所知,在 3.0 分钟应用程序暂停后,您必须处理该模式并使用 bgTask 调用您的服务。

标签: ios objective-c nsurlsession nsurlrequest background-mode


【解决方案1】:

这似乎与电源使用有关。 URL session 提供的后台上传很方便,它是由操作系统提供给你的——它提供发送数据,但它可以选择何时发送。

影响数据发送时间的因素包括设备是否连接到电源、数据连接的质量(发送数据需要多长时间和多少电量)、设备正在做什么(它可以合并多个上传)...

因此,您无法猜测或依赖在任何特定时间在后台执行的任何任务。

这种测试真的应该只在设备上进行,而不是连接到 Xcode,因为它会影响测试。取而代之的是,使用诸如 Charles 代理之类的东西来记录网络请求并使用该设备,将其放置一段时间,并可能打开并使用其他一些应用程序。您应该会看到最终发送的数据,但您必须等待。

【讨论】:

  • 是的,我对此进行了更多研究和挖掘,主要是关于电源和 Wi-Fi,这是 iOS 确定应用程序是否处于良好状态以执行任意任务的两个主要因素。当然,还有一些其他的因素,正如你所说的......
  • 不过,问题是如果应用程序在后台,则不会发送任何数据,而不是在 1 分钟后,而不是在 1 小时后。问题是我不是编写处理请求的类的人,所以目前我不能 100% 确定一切都正确配置(希望类本身有问题)。我会做一些测试,让你知道结果。我在连接到计算机的设备上进行测试,只是为了查看电池是否与此有关。当然,我稍后会断开设备。
  • 我只是为了好玩而尝试了一个 Charles 代理,它是一个方便的应用程序,但对我来说并没有那么有用。因为它需要 Wi-Fi 连接。当设备通过 Wi-Fi 连接时,会发送我的网络请求(就像我在问题中提到的那样)。问题在于蜂窝 (3G) 连接。无论如何,我实际上并不需要那个应用程序,因为我已经在我的服务器上看到了请求是否成功。我想我会尝试一下 NSURLSession,它的配置和后台任务。
  • @Whirlwind :您需要检查 API 是否在 3G 下触发。根据服务器条目,您无法确定 API 没有触发,因为它可能在 3G 连接中超时。另外,你有没有在appdelegate中实现handleEventsForBackgroundURLSession
  • @Poles 是的,我确实在 AppDelegate 中实现了 handleEventsForBackgroundURLSession。就查看文档而言,我从未发现过声明说这在 3G 上是不可能的。正如我所说,我做了一些研究和谈话,这种行为与自主任务有关。当您使用 +backgroundSessionConfigurationWithIdentifier 创建配置时:(当您在后台执行此操作时),iOS 会推断任务是自行决定的。仅当应用程序处于“良好状态”以运行它们时,自主任务才会运行。正如韦恩所说,电池在这方面(以及许多其他方面)发挥着重要作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多