beginBackgroundTaskWithExpirationHandler,从服务器下载数据

时间:2012-03-09 19:48:32

标签: iphone

我对beginBackgroundTaskWithExpirationHandler做了一些研究,我不认为我正确理解它。我的印象是,如果我们的应用程序进入后台,我可以在其中包含一个长任务,该任务继续运行。因此,当您第一次运行我们的应用程序时,您可以从我们的服务器下载更多数据,为用户提供更多信息。由于这可能需要一段时间,我希望此任务在后台和睡眠模式下运行(如果可能)。

我的原始函数没有在用户点击下载时调用的beginBackgroundTaskWithExpirationHandler,如下所示:

-(void) HandleDownload:(NSNotification *)notification
{
        DataManager *dmgr = [TestApp sharedDelegate].AppDataManager;
        NSString *nextPacketName = [dmgr GetNextPacketName];
        int totalNumberPackets = [dmgr GetRowCountForTable:@"Manifest"];
        if (nextPacketName == nil)
        { 
            [[NSNotificationCenter defaultCenter] removeObserver:self name:DownloadReferenceSequenceNotification object:nil];


            self.ProgressLabel.hidden = YES;
            self.ProgressBar.hidden = YES;
        }
        else
        {
            self.ProgressLabel.hidden = NO;
            self.ProgressLabel.text = [NSString stringWithFormat:@"Downloading %@", nextPacketName];
            self.ProgressBar.hidden = NO;
            self.ProgressBar.progress += 1. / (totalNumberPackets);

            WebServiceManager *wmgr = [WebServiceManager sharedInstance];
            [wmgr GetPacket:nextPacketName]; // This function creates the NSURL and starts the request
        }
}

假设应用程序位于前台,此函数可以正常工作。我尝试将此任务放在后台的是:

-(void) HandleDownload:(NSNotification *)notification
    {
UIApplication *app = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier taskID;
    taskID = [app beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"Background task not completed");
        [app endBackgroundTask:taskID];

            DataManager *dmgr = [TestApp sharedDelegate].AppDataManager;
            NSString *nextPacketName = [dmgr GetNextPacketName];
            int totalNumberPackets = [dmgr GetRowCountForTable:@"Manifest"];
            if (nextPacketName == nil)
            { 
                [[NSNotificationCenter defaultCenter] removeObserver:self name:DownloadReferenceSequenceNotification object:nil];


                self.ProgressLabel.hidden = YES;
                self.ProgressBar.hidden = YES;
            }
            else
            {
                self.ProgressLabel.hidden = NO;
                self.ProgressLabel.text = [NSString stringWithFormat:@"Downloading %@", nextPacketName];
                self.ProgressBar.hidden = NO;
                self.ProgressBar.progress += 1. / (totalNumberPackets);

                WebServiceManager *wmgr = [WebServiceManager sharedInstance];
                [wmgr GetPacket:nextPacketName]; // This function creates the NSURL and starts the request
            }
                NSLog(@"Time remaining: %f", app.backgroundTimeRemaining);
    }];

    if (taskID == UIBackgroundTaskInvalid) {
        NSLog(@"Failed to create background task identifier");
    }
    }

我是否正确地尝试将我长期运行的任务包装在beginBackgroundTaskWithExpirationHandler块中?它看起来并不像我,因为expiratinHandler块中的所有代码都不会被调用。提前谢谢!

1 个答案:

答案 0 :(得分:1)

我只是在研究同样的功能才第一次使用它,但我看到你似乎缺少的是对endBackgroundTask的平衡调用: 您在到期处理程序的顶部有它,但只有在达到时间限制时才会调用它。它需要在您尝试完成的任务结束时添加。假设您的流程在到期之前完成,它就会被调用。

-(void) HandleDownload:(NSNotification *)notification
    {
UIApplication *app = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier taskID;
    taskID = [app beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"Background task not completed");
        [app endBackgroundTask:taskID];

        DataManager *dmgr = [TestApp sharedDelegate].AppDataManager;
        NSString *nextPacketName = [dmgr GetNextPacketName];
        int totalNumberPackets = [dmgr GetRowCountForTable:@"Manifest"];
        if (nextPacketName == nil)
        { 
            [[NSNotificationCenter defaultCenter] removeObserver:self name:DownloadReferenceSequenceNotification object:nil];


            self.ProgressLabel.hidden = YES;
            self.ProgressBar.hidden = YES;
        }
        else
        {
            self.ProgressLabel.hidden = NO;
            self.ProgressLabel.text = [NSString stringWithFormat:@"Downloading %@", nextPacketName];
            self.ProgressBar.hidden = NO;
            self.ProgressBar.progress += 1. / (totalNumberPackets);

            WebServiceManager *wmgr = [WebServiceManager sharedInstance];
            [wmgr GetPacket:nextPacketName]; // This function creates the NSURL and starts the request
        }
            NSLog(@"Time remaining: %f", app.backgroundTimeRemaining);
            [app endBackgroundTask:taskID];
}];