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];
}