2

一旦用户退出应用程序,我正在尝试运行一些后台任务。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { //Check if our iOS version supports multitasking I.E iOS 4
        if ([[UIDevice currentDevice] isMultitaskingSupported]) { //Check if device supports mulitasking
            UIApplication *application = [UIApplication sharedApplication]; //Get the shared application instance
            __block UIBackgroundTaskIdentifier background_task; //Create a task object
            background_task = [application beginBackgroundTaskWithExpirationHandler: ^ {
                [application endBackgroundTask: background_task]; //Tell the system that we are done with the tasks
                background_task = UIBackgroundTaskInvalid; //Set the task to be invalid
                //System will be shutting down the app at any point in time now
            }];
            //Background tasks require you to use asyncrous tasks
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                //Perform your tasks that your application requires
                NSLOG(@"test1");
                [self performSelector:@selector(checkActivityCount) withObject:nil afterDelay:3];
                [application endBackgroundTask: background_task]; //End the task so the system knows that you are done with what you need to perform
                background_task = UIBackgroundTaskInvalid; //Invalidate the background_task
            });
        }
    }
}


-(void)checkActivityCount{
    NSLog(@"test");
    NSString *urlstring = @"https://exampleapp.com/api/v1/postactivity/?unreadfeedcount=yes";
    NSURL *url = [NSURL URLWithString:urlstring];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        BOOL success = [[JSON objectForKey:@"success"] boolValue];
        if (success) {
            if (![JSON[@"unread_activity_count"] isEqualToString:@"0"]) {
                // Schedule the notification
                UILocalNotification* localNotification = [[UILocalNotification alloc] init];
                localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
                localNotification.alertBody = [NSString stringWithFormat:@"You have %@ unread activities.",JSON[@"unread_activity_count"]];
                localNotification.alertAction = @"Show me the item";
                localNotification.timeZone = [NSTimeZone defaultTimeZone];
                localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;

                [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

                // Request to reload table view data
                [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];
            }
        }
    } failure:nil];
    [operationQueue addOperation:operation];

    [self performSelector:@selector(checkActivityCount) withObject:nil afterDelay:3000];

}

现在 test1 被记录,但 test 从不记录。我在代码中做错了吗?

4

1 回答 1

1

Using performSelector:withObject:afterDelay: pushes the request onto the queue for the thread. It doesn't wait for it. So immediately after you do that (even if something would pick the item from the queue in 3 seconds) you're telling the app that the background task is complete and the app gets shut down.

I haven't tried pausing like this, but try something more like:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self checkActivityCount];
    [application endBackgroundTask: background_task];
    background_task = UIBackgroundTaskInvalid;
});
于 2013-06-10T18:04:09.810 回答