我的应用代理需要在我的Microsoft SQL数据库进入后台或终止时解锁/锁定采购订单。
这是我的代码
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"App will enter background");
if ([purchaseOrderIsLocked boolValue] && [purchaseOrderAutoID intValue] > 0) {
NSLog(@"Unlock Purchase Order because app is in background %i", [purchaseOrderAutoID intValue]);
[self unlockPurchaseOrderWithAutoID:self.purchaseOrderAutoID];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"App will enter foreground");
if ([purchaseOrderIsLocked boolValue] == FALSE && [purchaseOrderAutoID intValue] > 0) {
NSLog(@"Lock Purchase Order because app is coming back %i", [purchaseOrderAutoID intValue]);
[self lockPurchaseOrderWithAutoID:self.purchaseOrderAutoID];
}
}
-(void)lockPurchaseOrderWithAutoID:(NSNumber *)autoID {
NSLog(@"lock purchase order called with autoID=%i",[autoID intValue]);
self.client = [SqlClientConnect connect];
[self.client executeQuery:[NSString stringWithFormat:@"UPDATE PURCHASE SET PURCHASELOCK = '9999' WHERE PURCHASEORDERNO = '%i'", [autoID intValue]]
withCompletionBlock:^(SqlClientQuery *query) {
if (query.succeeded) {
NSLog(@"locked purchase order");
purchaseOrderIsLocked = [NSNumber numberWithBool:YES];
} else {
[self queryFailedWithError:query.errorText];
}
}];
}
-(void)unlockPurchaseOrderWithAutoID:(NSNumber *)autoID {
NSLog(@"unlock purchase order called with autoID=%i",[autoID intValue]);
self.client = [SqlClientConnect connect];
[self.client executeQuery:[NSString stringWithFormat:@"UPDATE PURCHASE SET PURCHASELOCK = '0' WHERE PURCHASEORDERNO = '%i'", [autoID intValue]]
withCompletionBlock:^(SqlClientQuery *query) {
if (query.succeeded) {
NSLog(@"unlocked purchase order");
purchaseOrderIsLocked = [NSNumber numberWithBool:FALSE];
} else {
[self queryFailedWithError:query.errorText];
}
}];
}
}
好吧,这对我来说很好......但是当我运行应用程序时,这是我按下主页按钮时从日志中获取的内容
2011-12-14 13:41:20.558 MA Mobile[2267:707] App will enter background
2011-12-14 13:41:20.558 MA Mobile[2267:707] Unlock Purchase Order
because app is in background 18
2011-12-14 13:41:20.559 MA Mobile[2267:707] unlock purchase order called with autoID=18
它应该已经完成并发布了“未锁定的采购订单”,但事实并非如此 当我恢复应用程序时,这就是我得到的。
2011-12-14 13:41:44.741 MA Mobile [2267:707]应用程序将进入前台 1 2011-12-14 13:41:44.973 MA Mobile [2267:707]解锁采购订单
它就像恢复后运行块代码一样。这与块有关吗?我应该做些不同的事吗?
答案 0 :(得分:7)
一旦您离开该区块并返回-applicationDidResignActive:
,您的应用程序会立即暂停,您启动的异步通话基本上会暂停。您需要让应用程序知道您需要使用-beginBackgroundTaskWithExpirationHandler:在后台花更多时间。您可以使用以下示例中的代码执行此操作。有关长时间运行的后台任务的更多信息,请参阅iOS应用程序编程指南中的Background Execution and Multitasking。
这个简单的示例演示了如何在代码中使用此功能:
-(void)unlockPurchaseOrderWithAutoID:(NSNumber *)autoID
{
NSLog(@"unlock purchase order called with autoID=%i",[autoID intValue]);
// Start long-running background task
UIBackgroundTaskIdentifier bti = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
self.client = [SqlClientConnect connect];
[self.client executeQuery:[NSString stringWithFormat:@"UPDATE PURCHASE SET PURCHASELOCK = '0' WHERE PURCHASEORDERNO = '%i'", [autoID intValue]] withCompletionBlock:^(SqlClientQuery *query) {
if (query.succeeded) {
NSLog(@"unlocked purchase order");
purchaseOrderIsLocked = [NSNumber numberWithBool:FALSE];
} else {
[self queryFailedWithError:query.errorText];
}
// After we complete the asynchronous block, we need to let the system know we can suspend now
if( bti != UIBackgroundTaskInvalid )
[[UIApplication sharedApplication] endBackgroundTask:bti];
}];
}
答案 1 :(得分:1)
applicationWillResignActive
非常快,因此在应用程序丢失前景之前,您的任务很可能没有完成。此方法与某些具有相似名称的其他方法不同。系统不会询问您是否可以让应用程序辞职,而是告诉您应用程序现在正在重新签名。
查看iOS Developer guide有关“在后台执行Fininte长度任务”部分,了解如何让您的任务要求额外的时间来完成。
答案 2 :(得分:1)
applicationWillResignActive
可以提供信息,告诉您您的应用程序不再可用于接收用户交互,例如在收到呼叫或弹出系统警报时。
在您的情况下,这是因为用户点击了主页按钮,因此调用此方法,然后您的应用程序将进入后面调用applicationDidEnterBackground
的背景。这是您要执行此过程的位置,默认情况下,您只需要5秒钟即可完成所需操作。但是在iOS4中,您可以通过开始后台任务请求更多时间,最多10分钟。
您执行此方法大约需要五秒钟才能执行任何任务并返回。如果您需要额外的时间来执行任何最终任务,可以通过调用beginBackgroundTaskWithExpirationHandler:从系统请求额外的执行时间。实际上,您应该尽快从applicationDidEnterBackground返回:如果方法在时间用完之前没有返回,则应用程序将终止并从内存中清除。