Resume an interrupted synchronization where partial data has been downloaded to the device.
[DB resumePendingSynchronization]
[DB cancelPendingSynchronization];
… … … //turn on the resume synchronization option [[TestCRUDTestCRUDDB getSynchronizationProfile] setResumeSynchronization:YES]; MyCallbackHandlerForResumeSync *callback = [MyCallbackHandlerForResumeSync myCallbackHandlerForResumeSync]; [TestCRUDTestCRUDDB registerCallbackHandler:callback]; MyResumeSyncStatusListener *listener = [[MyResumeSyncStatusListener alloc] init]; SUPObjectList *groups = [SUPObjectList getInstance]; [groups add:[TestCRUDTestCRUDDB getSynchronizationGroup:@"default"]]; //submit a non-blocking sync request [TestCRUDTestCRUDDB beginSynchronize:groups withContext:nil withUploadOnly:NO withSyncStatusListener:listener]; … … …
//in the implementation of SUPDefaultCallbackHandler class … … … - (SUPSynchronizationActionType)onSynchronize:(SUPObjectList *) syncGroupList withContext:(SUPSynchronizationContext *)context { //sending a NOTE_CALLBACK_ONSYNC_TRIGGERED notification with the synchronization context object NSNotification *note = [NSNotification notificationWithName:NOTE_CALLBACK_ONSYNC_TRIGGERED object:context]; [self performSelectorOnMainThread:@selector(notify:) withObject:note waitUntilDone:NO]; switch (context.status) { … case SUPSynchronizationStatus_INTERRUPTED_WITH_PARTIAL_DATA: self.isInterruptedWithPartialData = YES; // By returning continue, the system waits for a request to resume or cancel the pending synchronization. // The synchronization queue is locked and disallows accepting any new incoming synchronization requests. // If returning SUPSynchronizationAction _CANCEL instead, the system automatically cancels the pending synchronization. // Application cannot resume the synchronization. // The synchronization queue is not locked and starts to accept new synchronization requests. return SUPSynchronizationAction_CONTINUE; break; } }
… … //that’s if the observer is added for “NOTE_CALLBACK_ONSYNC_TRIGGERED” [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onSyncCallbackStatusChanged:) name:NOTE_CALLBACK_ONSYNC_TRIGGERED object:nil]; … … … - (void)onSyncCallbackStatusChanged:(NSNotification *)notification { SUPSynchronizationContext *context = (SUPSynchronizationContext *)notification.object; … … … if (context.status == SUPSynchronizationStatus_INTERRUPTED_WITH_PARTIAL_DATA) { // cancel the pending synchronization when the interrupted status count reaches // the max as the application does not want to keep on trying to resume. // MAX_INTERRUPTED_STATUS number defined by the application code can be set to // a very a large number. if (MAX_INTERRUPTED_STATUS == self.interruptedStatusCount) { [self cancelPendingSync]; self.label.text = [NSString stringWithFormat:@"Resume sync is canceled. \n\tInterrupted status count reached the max: %d.", MAX_INTERRUPTED_STATUS]; } else { self.isInterruptedWithPartialData = YES; self.interruptedStatusCount++; //interrupted status received is not due to sync being disable – say by calling [DB disableSync] //in applicationDidEnterBackground. if (!self.isSyncDisabled) { NSDate *beginTime = [NSDate date]; // Provide your own logic in “isDeviceConnectedToInternet“ to use Reachability // API to check network connectivity before resumption attempt while(![self isDeviceConnectedToInternet] ) { NSDate *now = [[NSDate alloc] initWithTimeIntervalSinceNow:0.0]; // TIMEOUT defined by the application code to determine when the // application should stop checking for network connectivity in // case network connectivity never comes back. if ([now timeIntervalSinceDate:beginTime] >TIMEOUT) { NSLog(@"There is no network connection %d minute(s)", timeout/60]); [now release]; break; } [NSThread sleepForTimeInterval:1.0]; [now release]; } if ([self isDeviceConnectedToInternet]) { [self resumeSync]; } else { [self cancelPendingSync]; self.label.text = @"Resume sync is canceled.\n\tthere's no network connectivity for too long."; } } } … … … - (void)cancelPendingSync { NSLog(@"going to cancel pending sync..."); if (![TestCRUDTestCRUDDB cancelPendingSynchronization]) { NSLog(@”\tfailed to cancel pending syn"); } else { NSLog(@"\tpending sync has been cancelled."); } } - (void)resumeSync { if (!self.isInterruptedWithPartialData) { NSLog(@"no resume as there is no interrupted with partiald data"); return; } NSLog(@"going to resume sync..."); BOOL resumed = [TestCRUDTestCRUDDB resumePendingSynchronization]; self.isInterruptedWithPartialData = NO; if (!resumed) { NSLog(@"\tfailed to resume pending syn"); } else { self.resumeSyncCount++; NSLog(@"\tresume sync count: %d", self.resumeSyncCount)]; } } … … …
… … … - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"AppDelegate: did eneter background and about to disableSync"); [TestCRUDTestCRUDDB disableSync]; // Notify the observer that the application disables/interrupts the synchronization. // If it receives the SUPSynchronizationStatus_INTERRUPTED_WITH_PARTIAL_DATA status // from callback onSynchronize call later, do not try to resume immediately. NSNotification *n = [NSNotification notificationWithName:NOTE_SYNC_DISABLED object:nil]; [self performSelectorOnMainThread:@selector(notify:) withObject:n waitUntilDone:NO]; if([SUPApplication connectionStatus] == SUPConnectionStatus_CONNECTED || [SUPApplication connectionStatus] == SUPConnectionStatus_CONNECTING) { [SUPApplication stopConnection:0]; } } - (void)applicationWillEnterForeground:(UIApplication *)application { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_async(queue, ^ { @try { // Enable the synchronization. This does not resume the pending synchronization. // Instead it just sets the internal syncEnabled flag to true so that the synchronization // later on process would not be interrupted or canceled. [TestCRUDTestCRUDDB enableSync]; NSNotification *n = [NSNotification notificationWithName:NOTE_SYNC_ENABLED object:nil]; [self performSelectorOnMainThread:@selector(notify:) withObject:n waitUntilDone:NO]; [SUPApplication startConnection:30]; } @catch (NSException *ee) { // log an error or alert user via notification } } } …. …. …. - (void)onSyncDisabled:(NSNotification *)notification { self.isSyncDisabled = YES; } - (void)onSyncEnabled:(NSNotification *)notification { self.isSyncDisabled = NO; [self resumeSync]; }