(iOS) Offline Sync DB - Server (iOS) Offline Sync DB - Server sqlite sqlite

(iOS) Offline Sync DB - Server


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!


Your code has a couple of issues. One convention is to always check the return value before you test the error parameter. The error parameter might be set - even though the method succeeded.

When using NSURLConnection for anything else than a quick sample or test, you should also always use the asynchronous style with handling the delegate methods. Since using NSURLConnection properly may become quickly cumbersome and error prone, I would suggest to utilize a third party framework which encapsulates a NSURLConnection object and all connection related state info as a subclass of NSOperation. You can find one example implementation in the Apple samples: QHTTPOperation. Another appropriate third party framework would be AFNetworking (on GitHub).

When you use either the async style with delegates or a third party subclass, you can cancel the connection, retrieve detailed error or progress information, perform authentication and much more - which you can't with the synchronous API.

I think, once you have accomplished this and your approach works correctly, you may test whether the performance is acceptable. But unless you have large data - say >2 MByte - I wouldn't worry too much.

If your data becomes really large, say >10 MByte you need to consider to improve your approach. For example, you could provide the POST data as file stream instead a NSData object (see NSURLRequest's property HTTPBodyStream). Using a stream avoids to load all the POST data into RAM which helps alleviate the limited RAM problem.

If you have instead smaller POST data, but possibly many of them, you might consider to use a NSOperationQueue where you put your NSOperation connection subclass. Set the maximum number of concurrent operations to 2. This then may leverage HTTP pipelining - if the server supports this, which in effect reduces latency.

Of course, there might be other parts in your app, for example you create or retrieve the data which you have to send, which may affect the overall performance. However, if your code is sound and utilizes dispatch queues or NSOperations which let things perform in paralel there aren't many more options to improve the performance of the connection.