Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(iOS) Offline Sync DB - Server

Trying to implement an app which sends offline data stored on local db to web server when connected to internet. I use the code shown below. As far I have tested it works fine, not sure it will work fine for huge number of records. I would like to know whether any tweaking on this code may increase the performance???

NOTE

  • I know this would be a worst code for offline sync purpose, so trying to tweak it better.
  • Its a single way synchronization, from app to server.

    -(void)FormatAnswersInJSON {
    
      DMInternetReachability *checkInternet = [[DMInternetReachability alloc] init];
      if ([checkInternet isInternetReachable]) {
         if ([checkInternet isHostReachable:@"www.apple.com"]) {//Change to domain
            responseArray = [[NSMutableArray alloc] init];
    
            dispatch_async(backgroundQueue, ^(void) {
    
                NSArray *auditIDArray = [[NSArray alloc] initWithArray: [self getUnuploadedIDs]];
                for (int temp = 0; temp < [auditIDArray count]; temp ++) {
    
                    // Code to post JSON to server
    
                    NSURLResponse *response;
                    NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
                    if (!error) {
                        NSString *responseID = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
                        if ([responseID isEqualToString:@"ERROR"]) {
                            //Error uploading records
                        } else {
                           [responseArray addObject:responseID];
                        }
                    } else {
                       //Error
                       return;
                    }
                }
                dispatch_async( backgroundQueue, ^{
    
                    /* Based on return code update local DB */
                    for (int temp = 0; temp < [responseArray count]; temp ++) {
                       [self updateRecordsForID:[auditIDArray objectAtIndex:temp] withID:[responseArray objectAtIndex:temp]];
                    }
                });
            });
         }
      }
    }
    
    - (void)upload { //Called when internet connection available
    
        if(backgroundQueue){
            dispatch_suspend(backgroundQueue);
            dispatch_release(backgroundQueue);
            backgroundQueue = nil;
        }
        backgroundQueue = dispatch_queue_create("com.XXXX.TestApp.bgqueue", NULL);
        dispatch_async(backgroundQueue, ^(void) {
            [self FormatAnswersInJSON];
        });    
    }
    
like image 342
Nina Avatar asked Mar 12 '13 13:03

Nina


1 Answers

If this code were sitting in front of me, my approach would be:

  • Look at the use cases and define 'huge number of records': Will 50 record updates at a time occur regularly? Or will it be in 1s and 2s? Do my users have wifi connections or is it over the paid network?, etc.
  • If possible, test in the wild. If my user base was small enough, gather real data and let that guide my decisions, or only release the feature to a subset of users/beta tests and measure.
  • If the data tells you to, then optimize this code to be more efficient.

My avenue of optimization would be doing group processing. The rough algorithm would be something like:

for records in groups of X
  collect
  post to server {
    on return:
      gather records that updated successfully
      update locally
  }

This assumes you can modify the server code. You could do groups of 10, 20, 50, etc. all depends on the type of data being sent, and the size.

A group algorithm means a bit more pre-processing client side, but has the pro of reducing HTTP requests. If you're only ever going to get a small number of updates, this is YAGNI and pre-mature optimization.

Don't let this decision keep you from shipping!

like image 110
Gavin Miller Avatar answered Oct 12 '22 16:10

Gavin Miller