我了解后台任务可以实现,以执行某些需要超过分配3-4秒的进程- (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
时,从上面的代码中可以看出这一点,我从来没有收到过后台任务到期或进入Background Modes
以正确完成任务的任何迹象。
我首先感到困惑的是“做某事”调度甚至与后台任务有关,或者与任务相关联以让应用程序知道允许此过程在约10分钟内完成应用程序允许BG任务。
注意:我确保我已经在我的info.plist中允许Parse
,因为许多发布的解决方案指出可能是其他人的问题。
如果有人可以帮我正确地完成后台任务,我将非常感激。
FYI :这样做的主要目的是使用查询更新我的// 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.");
}
}];
}];
数据库,以将新用户(设备本地)值设置为数据库。如果我不够清楚,我会使用这个:
[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;
}
}];
}];
});
}
但它没有被调用。有几次假设这两次都是最快的,但是我试图处理情况(比如除了那些2之外的所有情况),成功更新Parse需要比关闭应用程序更长的时间。这是我做的:
{{1}}
答案 0 :(得分:1)
除了从[application endBackgroundTask:self.backgroundTaskId];
块之外调用dispatch_async
之外,您通常具有正确的结构,因此后台任务将在Parse操作完成之前结束。此外,如果您要更新的用户是当前登录的用户,则可以使用PFUser.currentUser
而不必搜索。
所以,你的applicationDidEnterBackground
应该是这样的:
- (void)applicationDidEnterBackground:(UIApplication *)application {
self.bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
// Clean up your background stuff
NSLog(@"Expired background task.");
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}];
// Begin your background stuff...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Doing something...");
// Do something...like update Parse DB
PFUser *user=[PFUser currentUser];
// Update User fields as required
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
NSLog(@"Saved user");
} else {
NSLog(@"Error:%@",error.localizedDescription);
}
NSLog(@"Background time remaining=%f",UIApplication.sharedApplication.backgroundTimeRemaining);
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}];
});
}