按下主页按钮后如何与服务器同步异步?

时间:2014-08-04 16:37:11

标签: ios ios7 asynchronous

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [_dataStore saveChanges];
    [_sync syncWithServerWithDate:[NSDate dateWithTimeIntervalSince1970:timestamp]];
}

-(void)syncWithServerWithDate:(NSDate *)date
{
    void(^postCompletionBlock)(FTjsonEvents *obj, NSError *error) = ^(FTjsonEvents *serverEvents, NSError *error) {
       ...
       NSLog(@"Post Completion block finished!");
    };

    void(^completionBlock)(FTjsonEvents *obj, NSError *error) = ^(FTjsonEvents *serverEvents, NSError *error) {
       ....
       NSLog(@"Fetch finished!");

       [self postRecordsSinceLastServerSyncTimestamp:[date timeIntervalSince1970] WithCompletion:postCompletionBlock];
    };

    NSLog(@"Syncing data...");
    [self fetchRecordsByDate:date WithCompletion:completionBlock];

}

我想与服务器同步以获取并发布最新数据。 由于这是通过异步完成块发生的,所以当我按下主页按钮时,我的类似乎会收集垃圾。同步永远不会到达服务器。

然而,在执行此操作时,可以轻松保存本地coredata:[_dataStore saveChanges]; 有没有办法让异步同步在后台保持活动状态直到完成?

1 个答案:

答案 0 :(得分:1)

applicationDidEnterBackground:的实施大约需要五秒钟来执行任务并返回。如果您需要额外的时间来执行任何最终任务,可以通过调用beginBackgroundTaskWithExpirationHandler:从系统请求额外的执行时间。在实践中,您应该尽快从applicationDidEnterBackground:返回。如果方法在时间用完之前没有返回,则应用程序将终止并从内存中清除。

在此方法退出之前,您应该执行与调整用户界面相关的任何任务,但是应根据需要将其他任务(例如保存状态)移动到并发调度队列或辅助线程。因为在applicationDidEnterBackground:中启动的任何后台任务可能在该方法退出之后才会运行,所以在开始执行这些任务之前,您应该请求额外的后台执行时间。换句话说,首先调用beginBackgroundTaskWithExpirationHandler:,然后在调度队列或辅助线程上运行任务。

以下是一个示例实现:

@interface XXAppDelegate (BackgroundStuff)

@property (nonatomic, assign) UIBackgroundTaskIdentifier backgroundTask;

@end

@implementation
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Request additional background time. 
    self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{

        [application endBackgroundTask:self.backgroundTask];
    }];

    // Start background task. 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //Background code goes here

        //Cleanup background task id
        [application endBackgroundTask:self.backgroundTask];
        self.backgroundTask = UIBackgroundTaskInvalid;
    });

}
@end