The DataAccess Class

The DataAccess Class

Take a look at the code created by the project template. Most of the work handling data will be performed in the DataAccess class, which can be found in DataAccess.h and DataAccess.m.

In this sample application the DataAccess class is responsible for:

  • The connection and login to Relativity Server.
  • Downloading data, persisting and exposing it as DADataTable instances.
  • Tracking changes and applying them back to Relativity Server.

The DataAccess class is a singleton. You can reach and use it anywhere via the sharedInstance property.

You will be using and changing the code in the DataAccess class quite a lot as you work through this sample application, so take a few moments to get familiar with it.

DataAccess.h

As you can see, if you look at DataAccess.h, the public interface to the DataAccess class is reasonably simple. Start by looking at the four methods.

// DataAccess.h
- (void)loadInitialData;
- (void)saveData;
- (void)saveDataInBackground;
- (DAAsyncRequest *)beginApplyUpdates;

loadInitialData method

The loadInitialData method is used to trigger an initial loading of Data.

WARNING: Never call loadInitialData asynchronously, as it itself calls threadedLoadInitialData in a background thread. This could cause problems with passing results back into the UI thread.

saveData and saveDataInBackground Methods

The saveData and saveDataInBackground methods are both used when your application is using a briefcase for offline data. You won't be using a briefcase in this tutorial, so you can ignore these for now.

beginApplyUpdates method

The beginApplyUpdates method is used to apply local changes to the data back to Relativity Server asynchronously.

The DataAccessDelegate Protocol

The DataAccess class also has a delegate property. It expects its delegate to support the DataAccessDelegate protocol.

//DataAccess.h
@protocol DataAccessDelegate
- (void)alertError:(NSString *)message;
- (BOOL)needLogin:(NSString **)login password:(NSString **)password;
@end

The DataAccess class will use the delegate to inform you when it requires login details or to let you know something has gone wrong.

AppDelegate.m

If you take a look at the applicationDidFinishLaunching method in AppDelegate.m, you will see the code sets the AppDelegate as the delegate for the DataAccess class and triggers an initial loading of Data.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{
     ...    
    // start loading & initializing data in the background
    [[DataAccess sharedInstance] setDelegate:self];
    [[DataAccess sharedInstance] loadInitialData];
    ...
}

DataAccess.m

The actual implantation of the DataAccess class in DataAccess.m is partly fully functioning implementation code and partly method stubs that you will need to implement. Most of the method stubs will contain commented example code showing you how a typical method implementation might look like. As you develop the sample application, you will implement many of these methods.

The Defines

DataAccess contains a set of defines that are used as settings. In the sample application you will only use the one to specify the URL to Relativity Server and define which schema to use.

#pragma mark -
#pragma mark Defines

#define APPLICATION_SUPPORT_FOLDER      @"RemObjects/Sample"
#define BRIEFCASE_FILENAME              @"Sample.briefcase"
#define BRIEFCASE_DATA_VERSION_KEY      @"Sample-BriefcaseVersion"
#define BRIEFCASE_DATA_VERSION          @"0.1"

// The following define specifies the name under which
// passwords will be saved in the keychain:
#define KEYCHAIN_APPNAME                @"RemObjects.Sample"

// The following defines specify the KEYS under which 
// username, password and server address will be stored in NSUserDefaults:
#define USERDEFAULTS_SERVERADDRESS_KEY  @"ServerAddress"
#define USERDEFAULTS_USERNAME_KEY       @"UserName"
#define USERDEFAULTS_PASSWORD_KEY       @"Password"

// Uncomment the following define to use AES encryption.
// The password should be the same as on server side.
//#define AES_PASSWORD                  @"type AES password here"


#warning Define your server address and Relativity domain name, below.

#define SERVER_URL                  @"http://localhost:7099/bin"

// Do not change when using Relativity Server
#define SERVICE_NAME                @"DataService" 

#define RELATIVITY_DOMAIN           @"MyDomain"
//#define RELATIVITY_SCHEMA         @"MySchema"

init Method

The init method of the DataAccess class performs the initial setup and configuration of the DataAbstract infrastructure. Lots of the code you will recognize as standard setup code. The listing below just highlights the part of the initialization code that creates a new DARemoteDataAdapter. Note that the DARemoteDataAdapter requires a delegate which is being set to the DataAccess instance being initialized in the init method.

- (id) init
{
    ...  
    // Set up rda and server access
    NSURL *url = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults];
    rda = [[DARemoteDataAdapter alloc] 
            initWithTargetURL:url 
            stringForKey:USERDEFAULTS_SERVERADDRESS_KEY
           ];
                                            
    [[rda dataService] setServiceName:SERVICE_NAME];
    ...
    [rda setDelegate:self];
    ...
}

downloadData method

The downloadDatamethod will be used to do an initial download of Data from the Relativity Server.

setUpData method

The setupData method is another internal method which will be called after successfully downloading data from the Relativity Server. In this method, you will set up any virtual fields (lookup and calculated fields) you require in your DADataTable instance.

triggerDataReady method

The triggerDataReady method is called once all the required data has been downloaded and configured and is ready to use.

threadedLoadInitialData method

The threadedLoadInitialData method is an internal method which prepares the initial data for usage. It first checks whether a briefcase (offline data) exists for our application. If it exists and is valid, it loads the data from the briefcase. If no Briefcase data exists, it tries to download data from the server. The threadedLoadInitialData method should not be called directly.

Notifications

The DataAccess class also declares two notifications.

#define NOTIFICATION_BUSYSTATUS_CHANGE  @"BusyStatusChangeNotification"
#define NOTIFICATION_DATA_READY         @"DataReadyNotification"

You will use these later on in the sample application to trigger actions in the UI when data arrives.