Monday, May 11, 2015

Welcome to the Cloud

Progress
I spent this week converting my test app to CloudKit.  It was a success.  As long as the devices that are syncing are connected to the cloud account they sync fine.  I no longer had the missing records problem I had with the CoreData test app.

And more importantly, I understand what is going on and can verify (in the iCloud dashboard) the records are making it to the cloud.  I added code to resync when a device reconnects to the cloud.  Another success!  

But what about when a device is not connected to the cloud?  What then?  So I embarked down this path.  The idea is to store the results of the last cloud sync to the local device and if the device is not connected then use that local store.  Sounds a lot like the Parse solution, huh!?

So my current plan is to have two service classes.  The first one, called LocalDataService, serves the data to the app.  The app always goes to LocalDataService for any CRUD operations on the data it needs. After the LocalDataService is done with the operation it notifies the app via NSNotifications (so the app can refresh its views).  

The LocalDataService defines the types of notifications it will send, and the app code should register to listen for the notifications that are important to it.  

The LocalDataService also is the only interface to the second service class, the RemoteDataService class.  The LocalDataService is set as the delegate of the RemoteDataService.  The RemoteDataService calls the delegate’s methods when something in the cloud has happened.

In practice, this is how I am thinking this will work.  Let’s take an example where the app wants to add an object.  

First the app calls the LocalDataService with the object to be saved.  The LocalDataService stores the object in it’s local store.  For a new object (and this is important) it gives this object a temporary id. This is important so it can find it later.

The LocalDataStore then notifies the app that it has successfully saved the object (via NSNotification).  The LocalDataStore then passes the object to the RemoteDataStore and asks it to save the object to the cloud.  

Assuming the RemoteDataStore’s operation is successful, it calls its delegate (the LocalDataStore) to inform it, that the object was successfully stored in the cloud.  The LocalDataStore looks the object up in it’s cache (using the temporary id that was passed through) and replaces its local representation with the cloud stored version.  Finally the LocalDataStore notifies the app that the object was saved (via NSNotification).  Yes this is a two notification process, but the way I’m thinking about this is they are really two different operations.

This seems simple enough on the surface but in practice it is harder than you think.  Corner cases abound.  What if the user deletes a record while the device is not attached to the cloud?  

So far my only solution to this (and I’ve seen others use this) is to keep some type of status flag on the locally stored objects.  While I think this will work (I’m still in the implementation phase) it does seem like I will be writing a lot more code than I had hoped.

The advantages I see that make this a compelling effort are:
  • The LocalDataStore can be anything I want (NSDocument, CoreData, A NoSQL database, etc)
  • The RemoteDataStore can also be anything I want (CloudKit, Parse, etc). I would not see it being CoreData based as that is the problem I am trying to avoid.
 
The disadvantages I see are:

  • I keep thinking someone has already solved this problem and probably a lot better than I have
  • I’m not sure this solutions lends itself to a generic solution, more of a pattern I think. Subsequently, there may be a “boat-load” of code to write.

Reading
I’m now two thirds the way through Spring in Action.  I want to finish this up by the end of May and then launch into the Manning Spring Boot book.  I also am pretty jazzed about working on a Spring application.

News That Caught My Eye
This new Kickstarter $9 computer caught my eye this week. Imagine if they can make it that cheaply by next year.  A little more miniaturization and we can all carry one around in our pocket.

Quick Looks
I went over several articles explaining Realm.  That seems like the perfect companion to my sync design.  I wonder if this is the future of mobile databases?

No comments:

Post a Comment