通过3G后台未发送数据

5

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

-(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运行,应用进入后台几分钟后,一个自定义蓝牙设备发送一些数据并将应用程序从挂起模式中唤醒。如果设备连接在3G上,则iOS应用程序在接收到数据后无法将其发送到服务器。我确定通过蓝牙发送的数据已被接收,因为它存储在本地数据库中。
还有一个重要的事实。如果通过Xcode运行应用程序,即使设备连接在3G上,该应用程序也会从后台发送数据。为了做到这一点,我先运行应用程序,然后点击Home按钮将其放入后台。
不知道为什么当应用程序通过电缆连接到Mac时,它会表现得不同,为什么数据无法通过3G(甚至2G)发送?
附加信息:
我不是尝试上传文件,而只是向服务器发送JSON。

你的设备多久能获取到蓝牙数据? - CodeChanger
@CodeChanger 一个应用程序每五分钟或更短时间从蓝牙获取数据。我确定已经接收到来自蓝牙的数据,因为我将其存储在本地sqlite数据库中。 - Whirlwind
根据我的了解,在3.0分钟后应用程序将被挂起,您需要处理该模式并使用“bgTask”调用您的服务。 - CodeChanger
1个回答

4
这似乎是关于电量使用的问题。URL会话提供的后台上传功能是一种便利,它由操作系统自行决定何时发送数据。
影响上传数据时间的因素包括设备是否连接电源、数据连接质量(发送数据需要多长时间和多少电力)、设备正在进行的其他任务(是否可以合并多个上传)等等。
因此,您不能猜测或指望任何任务在后台中的特定时间执行。
这种测试应该只在设备上进行,而不是连接到Xcode,因为这会影响测试。相反,使用Charles代理记录网络请求,并使用设备,在一段时间内保持设备开启并可能打开和使用其他应用程序。您应该会看到数据最终被发送,但您需要耐心等待。

是的,我做了更多关于这个问题的研究和挖掘,它主要与电源和Wi-Fi有关,这两个因素是iOS确定应用程序是否处于良好状态以执行自由任务的主要因素。当然,还有一些其他因素,就像你说的一样... - Whirlwind
然而,问题在于如果应用程序在后台运行,则永远不会发送任何数据,无论是1分钟还是1小时之后。问题是我不是编写处理请求的类的人,所以目前无法百分之百确定是否已正确配置(希望类本身有问题)。我将进行一些测试,并告知您结果。我只是在连接到计算机的设备上进行测试,以查看电池是否与此有关。当然,稍后我会断开设备的连接。 - Whirlwind
我只是出于好玩尝试了一下Charles代理,它是一个方便的应用程序,但在我的情况下并没有那么有帮助。因为它需要Wi-Fi连接。我的网络请求是在设备通过Wi-Fi连接时发送的(就像我在问题中提到的)。问题出现在蜂窝(3G)连接上。无论如何,我实际上并不需要那个应用程序,因为我已经在我的服务器上看到了请求是否成功。我想我会尝试一下NSURLSession、它的配置和后台任务。 - Whirlwind
@Whirlwind:你需要检查API是否在3G下触发。基于服务器条目,你不能确定API不会触发,因为它可能会在3G连接中超时。此外,你是否在appdelegate中实现了handleEventsForBackgroundURLSession - Poles
@Poles 是的,我已经在AppDelegate中实现了handleEventsForBackgroundURLSession。就查看文档而言,我从未发现有关3G不支持此功能的声明。正如我所说,我进行了一些研究和讨论,这种行为与自主任务相关。当您在后台创建使用+backgroundSessionConfigurationWithIdentifier:的配置时,iOS会将任务推断为自主任务。只有当应用程序处于“良好状态”时,自主任务才会运行。像Wain所说,电池在其中起着重要作用(以及许多其他因素)。 - Whirlwind

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