我正在创建一个在线商店风格的应用程序,用户可以在iPad上浏览不同的产品并订购这些产品。订购流程包括使用用户的数据和他想订购的相关产品创建xml文件。但有时可能会出现这样的情况:用户目前没有互联网连接,我想创建一些机制,每隔x分钟检查一次活动的互联网连接,然后尝试发送order-xml。它应重复此步骤,直到它连接到网络,然后在发送所有离线购物车时停止它。
我已经在网上搜索但只找到了在iOS 7上进行此操作的方法(使用UIBackgroundModes - fetch)。但我不想使用iOS 7,因为该应用程序已经完成,我不打算为iOS 7重新设计它(它是一个企业应用程序)。据我所知,iOS 6上当前的背景执行时间限制在15分钟左右,这是正确的吗?
关于如何解决的任何想法?
感谢。
编辑:
我在- (void)applicationDidEnterBackground:(UIApplication *)application
self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperationWithBlock:^{
[[InstanceHolder getInstance] startNetworkTimer];
}];
以下是接下来应该发生的事情:
- (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
函数:
self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperationWithBlock:^{
[[InstanceHolder getInstance] offlineCartLoop:nil];
}];
并将offlineCartLoop
函数更改为:
- (void) offlineCartLoop:(id)sender{
if([CommonCode isInternetConnectionAvailable]){
[self sendOfflineCarts];
}else{
[NSThread sleepForTimeInterval:10.0];
[self offlineCartLoop:nil];
}
}
似乎工作,但这会永远运行吗?还有什么我需要照顾的吗?
答案 0 :(得分:2)
没有你想要的解决方案 - 除非它在beginBackgroundTaskWithExpirationHandler授予的时间窗口内,否则无法在后台中定期检查每N分钟。 然而仅允许iOS6及更早版本的10分钟执行时间,或iOS7约3分钟。
如果您的应用不需要,您不能作弊并尝试使用后台模式,即使后台模式也不允许您随时自由运行。 即使iOS 7中的新背景模式也不允许您按计划运行。
即使你不想迁移到iOS7,你最好的最好的是iOS7 - 后台获取是相关模式(即使你不推拿)。使用该后台模式,您将有机会执行但而不是在您决定时,仅在操作系统决定时 - 并且其频率取决于用户如何使用您的应用程序。 使用iOS6,您的选择更受限制。
请参阅iOS: Keep an app running like a service
基本上没有连续后台执行,也没有定期后台执行,也没有应用决定何时在后台运行。
如果用户在使用您的应用下订单时没有互联网连接,那么无论如何您都应该通知他们(如果您不知道您的应用可能会被应用商店拒绝)也许告诉他们稍后再试。
如果他们处于飞行模式,用户将知道他们处于飞行模式,如果有临时中断(例如电话在电梯或隧道中),那么您的应用程序可以继续尝试,只要它是能够 - 在前台继续尝试每一分钟,然后当你切换到背景时你知道你还剩10分钟,继续尝试直到10分钟已经过期,然后向用户发布本地通知,通知他们应用程序无法由于缺乏连接而下订单。如果用户点击通知并启动您的应用,那么该应用将有机会再次重试。
如果仍然无法建立连接,那么就可以了,但您将有机会再次启动重试算法。但至少你已通知用户他们的订单没有通过。
答案 1 :(得分:0)
如果你需要知道的是数据连接是否以及何时可用,我建议反过来:而不是查询数据连接,让数据连接可用时通知你的应用程序。效率更高。
关于这个问题,我建议使用Reachability:您可以打电话询问是否可以访问特定的URL,并在连接可用时立即执行代码块。
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,请确保以线程安全模式执行
或者,可达性也可以在连接可用时通过NSNotification通知 - 这是实现相同结果的不同方式。由您决定哪一个更符合您的需求。