Use the Persistence Framework - iOS

The persistence framework is made available to the mobile app via the ServiceFactory class. The implementation is as follows:

ServiceFactory.h

  1. #import <Foundation/Foundation.h>
  2. #import "LocationService.h"
  3.  
  4. @interface ServiceFactory : NSObject
  5.  
  6. +(void)setOnline: (BOOL) online;
  7. +(BOOL)isOnline;
  8.  
  9. +(id<LocationService>) getLocationService;
  10.  
  11. @end

ServiceFactory.h

  1. #import "ServiceFactory.h"
  2. #import "LocationServiceWeb.h"
  3. #import "LocationServiceDB.h"
  4. #import "EventManager.h"
  5. #import "User.h"
  6.  
  7. @implementation ServiceFactory
  8.  
  9. static bool _online = YES;
  10.  
  11. +(BOOL)isOnline {
  12. return _online;
  13. }
  14.  
  15. +(void)setOnline: (BOOL) online {
  16. _online = online;
  17. }
  18.  
  19. +(id<LocationService>) getLocationService {
  20. id<EventManager> em = (id<EventManager>)[[UIApplication sharedApplication] delegate];
  21. if (_online) {
  22. LocationServiceWeb *lsw = [[LocationServiceWeb alloc] init];
  23. [lsw setUserId:[em getUserId]];
  24. [lsw setToken:[em getToken]];
  25. return lsw;
  26. } else {
  27. LocationServiceDB *lsdb = [[LocationServiceDB alloc] init];
  28. [lsdb setUserId:[em getUserId]];
  29. return lsdb;
  30. }
  31. }
  32.  
  33.  
  34. @end

Comments:

  • Lines 9 - 17: The online / offline status is managed by a static variable named _online and two helper methods.
  • Lines 19 - 13: Based on the online / offline status, return either a web-based location service, or a db-based location service. (Note: The implementation of the class LocationServiceDB will be described in the next article.

The only remaining task is to update the mobile app code to leverage the new service. For purposes of simplicity, I'll describe the replacement code for the LocationListViewController class:

  1. // ...
  2.  
  3. -(void)viewWillAppear:(BOOL)animated {
  4. [super viewWillAppear: animated];
  5. if (requiresRefresh) {
  6. requiresRefresh = NO;
  7. id<LocationService> ls = [ServiceFactory getLocationService];
  8. NSError* error = nil;
  9. [ls setDelegate:self];
  10. if (![ls getMany:@"" error:&error]) {
  11. NSLog(@"%@", error.localizedDescription);
  12. }
  13.  
  14. }
  15.  
  16. }
  17.  
  18. /*
  19.  * This class manages the CRUD operations for locations, and this method is called when
  20.  * a response is received from the server.
  21.  */
  22. -(void) contentLoaded:(ContentResponse *)response {
  23. if (response.rc < 0) {
  24. NSLog(@"Error communicating with the server: %@", response.descr);
  25. return;
  26. }
  27. if (response.action == CB_LIST) {
  28. NSMutableArray *loadedLocs = [response getItems];
  29. [locations removeAllObjects];
  30. [locations addObjectsFromArray:loadedLocs];
  31. } else if (response.action == CB_CREATE_JSON) {
  32. [locations addObjectsFromArray:[response getItems]];
  33. } else if (response.action == CB_UPDATE) {
  34. FishingSpot *updatedSpot = [[response getItems] objectAtIndex:0];
  35. for(int x=0; x < locations.count; x++) {
  36. FishingSpot *curSpot = [locations objectAtIndex:x];
  37. if (curSpot.ID == updatedSpot.ID) {
  38. [locations replaceObjectAtIndex:x withObject:updatedSpot];
  39. break;
  40. }
  41. }
  42. } else if (response.action == CB_DELETE) {
  43. for(int x=0; x < locations.count; x++) {
  44. FishingSpot *curSpot = [locations objectAtIndex:x];
  45. if (curSpot.ID == response.rc) {
  46. [locations removeObjectAtIndex:x];
  47. break;
  48. }
  49. }
  50. }
  51. [self.locationTableView reloadData];
  52. }
  53.  
  54. // ...

Comments:

  • Line 7: The ServiceFactory is used to retrieve a LocationService.
  • Line 9: The current class is specified as the delegate for the service.
  • Lines 10 - 12: Attempt to retrieve a list of all FishingSpot objects. If successful, contentLoaded: will be invoked. If not successful, print an error.
  • Lines 22 - 52: This method is invoked when data has been retrieved, and the contents have been parsed. Based on the operation completed, update the table view appropriately.

This completes the iOS rewrite of the web-based persistence framework. I'll now describe how to implement the same framework for Android.