Viewing the SUP101Appdelegate Files

The SUP101Appdelegate.h and SUP101Appdelegate.m files are created when you create the Xcode project; however, you deleted the automatically generated versions and replaced them with the ones added from the source code zip file.

The SUP101Appdelegate files make use of the SUPApplication and SUPDataVault APIs to show how to store and retrieve sensitive data (such as Sybase Unwired Platform credentials) using a PIN.

The applicationDidFinishLaunching: method checks to see if the application has been run before, then shows a dialog to have the device user enter a PIN to unlock the application. If running for the first time, the Sybase Unwired Platform user's password is also requested.

Control passes to the initializeSUP101 method. This code sample does one of two things depending on whether the application has been run before:

if(self.firstrun)
{
  NSLog(@"Running the app for the first time.");
        
        
        
  // If the application is being run for the first time, we do the following:
  //      1. Remove the messaging data vault created by earlier versions of the application, if it exists.
  //      2. Remove the SUP101 data vault created by earlier versions of the application, if it exists.
  //      3. Create the messaging vault using the PIN as the password, leaving it unlocked for use by the messaging layer.
  //      4. Create the SUP101 data vault using the PIN as the password, and store the SUP username/password credentials 
  //                  and a database encryption key in the vault.
  //      
  @try
  {  
    NSLog(@"Delete preexisting messaging vault");
    [SUPDataVault deleteVault:kMessagingDataVaultID];
  }
  @catch(NSException *e)
  {  
    // Ignore any exception
  }
  @try {
         NSLog(@"Delete preexisting SUP101 data vault");
         [SUPDataVault deleteVault:kSUP101DataVaultID];
       }
  @catch(NSException *e)
  {  
    // Ignore any exception
  }
        
  @try {
    NSLog(@"Create new SUP101 data vault and store credentials and a generated encryption key");
    sup101vault = [SUPDataVault createVault:kSUP101DataVaultID withPassword:self.pin withSalt:kSUP101DataVaultSalt]; // creates the vault
    [sup101vault setString:@"password" withValue:self.SUPPassword];
    [sup101vault lock];
   }
   @catch (NSException *exception) {
     NSLog(@"Exception in creating new SUP101 data vault: %@: %@",[exception name], [exception reason]);
   }
   @try {
     NSLog(@"Create new messaging vault and leave it unlocked");
     messagingvault = [SUPDataVault createVault:kMessagingDataVaultID withPassword:self.pin withSalt:kDVStandardSalt];
   }
   @catch (NSException *exception) {
     NSLog(@"Exception in creating new messaging data vault: %@: %@",[exception name], [exception reason]);                
   }

}
else
{
  // If the application has been run before, we get the PIN from the user, and use it to unlock the existing messaging data vault
  // (otherwise the messaging layer cannot start).
  //
  //
  NSLog(@"App has been run before.");
  @try {
    NSLog(@"Unlock messaging vault");
    messagingvault = [SUPDataVault getVault:kMessagingDataVaultID];
    [messagingvault unlock:self.pin withSalt:kDVStandardSalt];
  }
  @catch (NSException *exception) {
    NSLog(@"Exception unlocking messaging data vault: %@: %@",[exception name],[exception reason]);
    [self showNoTransportAlert:kSUP101ErrorBadPin];
  }
        
}

This code sample sets up the Application API settings for connection to the Unwired Server and registers with the Unwired Server.

// Start up the messaging client. This will attempt to connect to the server. If a connection was
// established we can proceed with login. See onConnectFailure: for more information about handling connection failure.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onConnectSuccess:) name:ON_CONNECT_SUCCESS object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onConnectFailure:) name:ON_CONNECT_FAILURE object:nil];
self.connectStartTime = [NSDate date];
SUPApplication* app = [SUPApplication getInstance];

@try {
  sup101vault = [SUPDataVault getVault:kSUP101DataVaultID];
  [sup101vault unlock:self.pin withSalt:kSUP101DataVaultSalt];
        
  app.applicationIdentifier = @"sup101";
  SUP101CallbackHandler *ch = [SUP101CallbackHandler getInstance];
  [ch retain];
  [app setApplicationCallback:ch];
        
        
  SUPConnectionProperties* props = app.connectionProperties;
  [props setServerName:self.SUPServerName];
  [props setPortNumber:[self.SUPServerPort intValue]];
  [props setUrlSuffix:@""];
  [props setFarmId:self.SUPFarmID];

        
  SUPLoginCredentials* login = [SUPLoginCredentials getInstance];
  if(self.SUPManualRegistration)
  {
    login.username = self.SUPConnectionName;
    login.password = nil;
    props.activationCode = self.SUPActivationCode;
  }
  else
  {
    login.username = self.SUPUserName;
    login.password = [sup101vault getString:@"password"];   
    props.activationCode = nil;
  }
  props.loginCredentials = login;
        
  [app registerApplication:30];

This code sample does one of two things depending on whether the application has been run before:

// Normally you would not delete the local database. For this simple example, though,
// deleting and creating an empty database will cause all data to be sent from the
// server, and we can use [CallbackHandler onImportSuccess:] to know when to proceed.        
[SUP101SUP101DB deleteDatabase];
[SUP101SUP101DB createDatabase];
SUPConnectionProfile *cp = [SUP101SUP101DB getConnectionProfile];
[cp.syncProfile setDomainName:@"default"];
[cp enableTrace:NO];
[cp.syncProfile enableTrace:YES];

// Generate an encryption key for the database.
[SUP101SUP101DB generateEncryptionKey];
[SUP101SUP101DB closeConnection];
// Store the encryption key in the data vault for future use.
[sup101vault setString:@"encryptionkey" withValue:[cp getEncryptionKey]];
        
// Since we are creating the database from scratch, we set the encryption key for the new database
        
// If we were using the database from a previous run of the app and not creating it each time, an application should run the code below instead.
// To successfully access a previously encrypted database, we set the key used by the connection profile.
NSString *key = [sup101vault getString:@"encryptionkey"];
NSLog(@"Got the encryption key: %@",key);
[cp setEncryptionKey:key];
[SUP101SUP101DB closeConnection];
        
[SUP101SUP101DB setApplication:app];

while([app registrationStatus] != SUPRegistrationStatus_REGISTERED)
{
  [NSThread sleepForTimeInterval:1.0];
}
while([app connectionStatus] != SUPConnectionStatus_CONNECTED)
{
  [NSThread sleepForTimeInterval:1.0];
}

Once the server connection is made, the onConnectionStatusChanged: method in the callback handler posts an ON_CONNECT_SUCCESS notification, and the SUP101AppDelegate's onConnectSuccess: method is called. This performs a login to the Unwired Server, using the username from the application settings, and the password from the data vault.