Skip to Content

/wp-content/uploads/2014/10/09_556217.png

This blog content is joint work with Thasneem Yasmin Hameed from the SAP Development team in Dublin, California – special thanks to Thasneem!


Hi everyone!


Let’s start with the last question.


What if the OData Producer fails one of the queued requests during a flush?


In an online scenario, the result of any request is immediately propagated to the client. For example, a create request call will immediately return a 201 if it is successful or an error message if the entry was not created successfully at the OData producer end. Upon receiving the result, the client can manage subsequent requests based on the outcome.


But this doesn’t happen in an offline scenario where there is no connectivity. For example, if an application makes a create request in offline mode, the corresponding data is only available in the local database on the device. The application could continue to do an update on the same data while still being offline.


Another scenario might be where an entry may have been deleted on the OData producer, but an offline application, which is unaware of this change, may still schedule an update on it. 

A typical scenario for an offline app is to schedule a series of requests when offline. When the device becomes online and a flush call is initiated, all of these requests are sent to the server. For each request queued in the flush, the outcome must be propagated to the application.

/wp-content/uploads/2014/10/queue_557391.png

The SDK provides the SODataOfflineStoreRequestErrorDelegate protocol for this purpose. This delegate has one method


  • offlineStoreRequestFailed:request:error: During a flush, called once for each request that fails against the backend OData Producer.


For example if 10 requests are being queued in a flush call and result in 3 requests failing at the backend, then the offlineStoreRequestFailed:request:error: will be called 3 times, each time with the error message specific to the failed request. In the scenario mentioned above where there is an offline create and then an update on the same entry in offline mode, then during a flush call, if the create has fails at the server, the offlineStoreRequestFailed:request:error: will be called first for the create request failure and subsequently for the update request failure, which of course will fail (since there is no such entry as the create had failed).

/wp-content/uploads/2014/10/errors_556218.png

Note: The call to this delegate method cannot stop or modify the flush operation. So, if a series of 10 requests are sent in a flush call, then the flush will execute all the 10 requests in the backend regardless of whether some of the requests fail in the process (thereby invoking the delegate method for each failure.) For apps that expect to have large numbers of requests in each flush we strongly recommend that the apps be written to try to remove the possibility of such errors. For example, a create can be made not to fail if the application is written to do some validation so invalid property values are never sent to the server in the first place.


An offline application can also view the offline request errors by means of the Error Archive, which is a collection of offline request errors stored on the local device. When an offline request fails during a flush call, the error is immediately added to the error archive. The application can retrieve the error archive from the offline store with a simple read request with the resource path set to “ErrorArchive”.

/wp-content/uploads/2014/10/error_archive_556219.png

The ErrorArchive collection can be queried the same way as any other OData collection, so you can use $filter, $top etc. query options to modify the search. There is no limit to the number of errors that will be stored in the archive, and it is up to the application to manually execute delete operations against the archive entries to purge them.


So let’s try to code. Don’t forget to declare and set the SODataOfflineStoreRequestErrorDelegate.

01  [offlineStore setRequestErrorDelegate:self];

And the method will be called back. Most likely you want to do two things in the pseudo code below.

01  - (void) offlineStoreRequestFailed:(SODataOfflineStore*) store
02                             request:(id<SODataRequestExecution>) requestExecution
03                               error:(NSError*) error
04  {
05    // A. Notify the user a CUD operation was failed
06    // B. Purge an item from the error archive
07  }

Implementing A. is nothing special, after examining the requestExecution and error objects, a dry (boring) popup with an error message might be just fine, but as you know iOS devices provide fancy options to notify users with cool user experience, it is all up to our imagination with the brand-new technology 🙂


Here comes another good question with B. – how to purge them?


We’ll discuss in the next blog!



See you in the next blog,

Ken


List of blogs

To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

      1. M B

        that webinar only gives an introduction. but a series of tutorials with a sample project using each api will be very useful .

        (0) 
  1. Jose Manuel Puche

    Hi Kenichi:

    I have a question about what happened if you execute a create operation onto an entity and then you execute a update or delete operation onto the same entity? Will these operations combined in any manner?

    I mean, if you execute a create and then a delete operation, how many operations will it send onto backend system, 2 or 1?

    Regards,

    José

    (0) 
    1. Kenichi Unnai Post author

      Hi Jose,

      The operation sequence in the queue is the same how you issue CRUD locally, no combining of the operations in an offline store. This is because the offline store doesn’t know whether there will be side-effects in the server from each operation.

      So the answer is 2.

      I’ll cover the topic related to it in the next blog, thanks for the input 🙂

      Best regards,

      Ken

      (0) 

Leave a Reply