首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于iOS 6的长期后台任务执行

基于iOS 6的长期后台任务执行
EN

Stack Overflow用户
提问于 2014-02-26 13:50:18
回答 2查看 1.4K关注 0票数 0

我正在创建一个在线商店风格的应用程序,用户可以在他们的iPad上浏览不同的产品并订购这些产品。订购过程包括使用用户的数据和他想订购的相关产品创建xml文件。但有时可能会出现这样的情况,用户现在没有互联网连接,我想创建一些机制,每x分钟检查一次活跃的互联网连接,然后尝试交付订单-xml。它应该重复这一步骤,直到它连接到网络,然后停止它,当所有的离线手推车已经发送。

我已经搜索了网络,但只有在iOS 7(使用UIBackgroundModes - fetch)上找到了这样的方法。但是我不想使用iOS 7,因为应用程序已经完成了,我也不打算重新设计iOS 7(这是一个企业应用程序)。据我所知,iOS 6上当前的后台执行时间限制在15分钟左右,对吗?

对如何解决这个问题有什么想法吗?

谢谢。

编辑:我在- (void)applicationDidEnterBackground:(UIApplication *)application中尝试了以下几种方法

代码语言:javascript
复制
self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperationWithBlock:^{
    [[InstanceHolder getInstance] startNetworkTimer];
}];

接下来应该发生的事情如下:

代码语言:javascript
复制
- (void) startNetworkTimer{
    if ([CommonCode getAllOfflineCartsForClient:nil].count > 0){
        NSTimer *pauseTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(offlineCartLoop:) userInfo:nil repeats:YES];
    }

}

- (void) offlineCartLoop:(id)sender{
    if([CommonCode isInternetConnectionAvailable]){
        [self sendOfflineCarts];
        [sender invalidate];
    }
}

startNetworkTimer按其应有的方式被调用,但是它没有调用offlineCartLoop函数:-(

编辑2:

我认为计时器是问题所在。我现在像这样调用offlineCartLoop函数:

代码语言:javascript
复制
self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperationWithBlock:^{
    [[InstanceHolder getInstance] offlineCartLoop:nil];
}];

并将offlineCartLoop函数更改为:

代码语言:javascript
复制
- (void) offlineCartLoop:(id)sender{
    if([CommonCode isInternetConnectionAvailable]){
        [self sendOfflineCarts];
    }else{
        [NSThread sleepForTimeInterval:10.0];
        [self offlineCartLoop:nil];
    }
}

似乎可行,但这会永远持续下去吗?还有什么需要我处理的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-26 16:11:29

对于您想要的,没有解决方案--没有能够定期检查背景中每N分钟的东西,除非它是在beginBackgroundTaskWithExpirationHandler批准的时间窗口内。但是,对于iOS6和更早版本,这只允许执行10分钟,对于iOS7则只允许执行大约3分钟。

如果你的应用程序不需要,你不能欺骗和尝试使用背景模式,甚至背景模式也不允许你在任何时候自由运行。即使iOS 7中的新背景模式也不允许您按计划运行。

最好的结果实际上是iOS7,即使您不想迁移到iOS7 --背景获取是相关模式(即使您正在推动而不是抓取)。在这种背景模式下,您将能够有机会执行,但不是当您决定,只有当操作系统决定-频率取决于用户如何使用您的应用程序。有了iOS6,您的选择就更少限制了。

请参阅iOS:让应用程序像服务一样运行

基本上没有连续的后台执行,也没有周期性的后台执行,也没有决定什么时候在后台运行的应用程序。

如果用户在使用你的应用程序下订单时没有互联网连接,那么无论如何你都应该通知他们(如果你没有,那么你的应用程序可能会被应用商店拒绝),也许告诉他们以后再试一次。

如果他们处于飞行模式,用户就会知道他们在飞行模式,如果有临时中断(比如手机在电梯或隧道里),那么你的应用程序可以继续尝试,只要它能够--在前台时,每分钟都试一次,然后当你切换到你知道你还有10分钟的背景时,继续尝试,直到10分钟几乎过期,然后向用户发送本地通知,通知他们由于缺乏连接性,应用程序无法下单。如果用户单击通知并启动应用程序,则该应用程序将有机会在此重新尝试。

如果您仍然无法建立连接,那么就这样吧,但是您将有机会再次启动重试算法。但至少你已经通知了用户他们的订单还没有通过。

票数 2
EN

Stack Overflow用户

发布于 2014-02-26 15:15:01

如果您需要知道的是数据连接是否可用以及何时可用,我建议将此过程倒转:不要查询数据连接,而是在数据连接可用时通知您的应用程序。更有效率。

关于这个主题,我建议使用可达性:您可以打电话知道某个特定的URL是否是可访问的,并在连接可用时立即执行一段代码。

代码语言:javascript
复制
Reachability *reach = [Reachability reacabilityWithHostName:@"www.myservice.com"];

...

reach.reachableBlock = ^(Reachability *reach) {
    // Process the requests queue
    // You should implement the method below
    [self processQueue];
}

...

if ([reach isReachable]) {
    // Upload the XML file to the server
    // You should implement the method below
    [self uploadToServer:myRequest];
} else {
    // Enqueue your request somewhere, for example into an NSArray
    // You should implement the method below
    [self addToQueue:myRequest];
}

上面的代码应该是一个展示(它不能正常工作),使用它作为参考。我可以说,reach变量应该是类属性或数据成员,并且应该初始化一次。此外,如果将请求排入NSArray中,请确保在线程安全模式下进行。

或者,当连接可用时,Reachability也可以通过NSNotification通知--这是实现相同结果的不同方式。由你决定哪一个更适合你的需要。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22043384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档