據我瞭解,後臺任務可以實現以執行需要比分配的3-4秒applicationDidEnterBackground
你使用像這樣提供了更多的特定過程:iOS的後臺任務沒有完成
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
// Clean up your background stuff
NSLog(@"Finsihed background task.");
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Begin your background stuff...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do something...like update Parse DB
NSLog(@"Doing something...");
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
不幸的是,我似乎在這裏失去一些東西。雖然我收到Doing something...
這是從上面的代碼是相當明顯的,我從來沒有收到任何種類的指示後臺任務過期或曾經進入expirationHandler
正確完成任務。
我很困惑,「做某事」調度如何與後臺任務相關,或者與任務相關聯,讓應用程序知道允許此過程在應用程序允許的〜10分鐘內完成BG任務。
注意:我確保我已允許在我的info.plist中使用Background Modes
,因爲許多發佈的解決方案指出可能是其他人的問題。
如果有人可以幫助我正確地完成後臺任務,我會非常感激。
FYI:這樣做的主要目的是用查詢更新我的Parse
數據庫,以將用戶新值(本地到設備)值設置爲數據庫。這是我會使用的情況下,我不是足夠清楚:
// Do something...like update Parse DB
NSLog(@"Doing something...");
. . .
PFQuery *query = [PFQuery queryWithClassName:@"_User"];
// Retrieve the object by id
[query getObjectInBackgroundWithId:<SOME_OBJECT_ID> block:^(PFObject *userInfo, NSError *error) {
// Save user info to current user info on Parse
[userInfo saveInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Could not update Parse with error: %@", error);
}
else {
NSLog(@"Updated Parse successfully.");
}
}];
}];
UPDATE: 我曾試着撥打解析塊內[application endBackgroundTask:bgTask];
但它不會被調用。有幾次它假設這兩次都是最快的,但我正在嘗試處理更新Parse成功所需的時間比關閉應用程序所需的時間更長的情況。下面是我做的:
- (void)applicationDidEnterBackground:(UIApplication *)application {
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
NSLog(@"Good for you.");
}
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
self.backgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskId];
NSLog(@"done");
}];
// Begin your background stuff...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do something...like update Parse DB
NSLog(@"Doing something...");
PFQuery *query = [PFQuery queryWithClassName:@"_User"];
// Retrieve the object by id
[query getObjectInBackgroundWithId:<SOME_OBJECT_ID> block:^(PFObject *userInfo, NSError *error) {
// Save user info to current user info on Parse
userInfo[@"test"] = [NSNumber numberWithInteger:12345];
[userInfo saveInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Could not update Parse with error: %@", error);
[application endBackgroundTask:self.backgroundTaskId];
self.backgroundTaskId = UIBackgroundTaskInvalid;
}
else {
NSLog(@"Updated Parse successfully.");
[application endBackgroundTask:self.backgroundTaskId];
self.backgroundTaskId = UIBackgroundTaskInvalid;
}
}];
}];
});
}
到期處理程序,如果你的後臺任務到期時纔會調用。由於在過期之前調用'endBackgroundTask',處理程序將不會被調用。我懷疑你的問題是你在後臺調度Parse活動,但接着調用'endBackgroundTask'。只有在更新完成後,才應該調用'endBackgroundTask'。 – Paulw11
好吧,很高興知道。我仍然不確定如何讓'dispatch_async'正確執行任務。例如,我試圖讓它在10分鐘後爲NSLog調用一個GCD,並且它從未被解僱。 –
它的工作原理很簡單'做些什麼......'但我無法完成任何需要超過應用程序終止時間的事情:\ –