Now that the Names application can add and remove names from an UltraLite database, you will add synchronization to a consolidated database server on your computer. In order to complete this lesson you will need to have SQL Anywhere installed on your computer. If you receive any errors or warnings during this lesson, make sure you have configured your installation correctly and have the proper environment variables set.
Open Sybase Central.
Under the Tools menu, choose SQL Anywhere 12 -> Create Database....
Click Next on the Welcome screen and the Select a Location screen.
Choose a location to save the database file and name it Names.db and click Finish. The rest of the options can remain as their defaults
When the database has been created, close the popup window.
In order to synchronize, you will first need to create a table on the consolidated database:
If the left-hand selection is Tasks or Search, change it to Folders, by selecting Folders from the View menu.
In the Folders pane, Control-click the Tables element under the Names database and select New -> Table.
Name the table "Names" and click Finish. This will create the table and ready the cursor to name the primary key column of the table.
Name the primary key of the table "id" with a uniqueidentifier type.
Click the [...] button under the Value heading and set the default value to the User-defined value: NEWID().
Make sure the Literal string checkmark is not checked and click OK.
Add another column by clicking the New Column button on the toolbar.
Name the new column "name" of type VARCHAR and size 254.
Uncheck the Null checkmark for the name column.
Check the Unique checkmark for the name column.
Click the Save button on the toolbar.
Disconnect from the database.
In order to set up MobiLink, the system must have an ODBC data source for the consolidated database. Before you can setup the ODBC data source, you must first install the SQL Anywhere ODBC driver:
Open a Terminal.
Type the following command to create the ODBC data name source:
dbdsn -w "Names" -c "UID=dba;PWD=sql;DBF=/Users/user/Names.db" |
If the location of your database is different than this, make sure to update the DBF option.
In order for MobiLink to perform the synchronization, you need to configure the synchronization scripts. To make configuration easier, Sybase Central provides script templates for many common forms of synchronization.
In Sybase Central:
Under the Tools menu, select MobiLink 12 -> New Project.
Name the project NamesProject and click Next.
Check Add a consolidated database to the project. Provide a Database display name of NamesCondb. Provide a connection string of 'UID=dba;PWD=sql;DSN=Names"
. Note that you can also build this string by clicking the Edit button. Click Next.
Select Create a new model and click Next.
Check Add a remote schema name to the project, enter a name, and, with UltraLite schema selected, click Finish. This remote schema is not actually used, but since the remote schema is on the iPhone, this option is the simplest.
A message appears saying that MobiLink has not yet been installed and asks if it should be installed now. Click Yes. This will create the tables required by MobiLink in the database, as well as some stored procedures.
Enter NamesModel as the model name and click Next.
Check all three checkboxes to acknowledge the MobiLink requirements, and click Next. In order for synchronization to function correctly, MobiLink assumes a few things about the primary keys of the tables. Since the Names application already abides by these assumptions, no changes are required.
Choose the NamesCondb consolidated database and click Next.
Choose No, create a new remote database schema and click Next.
Check the Names table from the list of tables and click Next. Any other tables listed are used by MobiLink behind the scenes and can safely be ignored for synchronization.
For the Download type, choose Timestamp-based download. This option provides a good default implementation of synchronization by only synchronizing changes since the last sync. This option will save bandwidth for the iPhone since no unnecessary data will be transferred.
Since all other settings should be kept as their defaults, click Finish.
If you would like to see the other options available as MobiLink templates, you can click through all of the steps in the wizard.
Now that the synchronization model has been created, it should be visible in the left- hand side Folders view. If the Folders view is not showing, make sure the menu View -> Folders is checked.
To deploy the synchronization model:
Control-click the NamesModel in the Folder view and select Deploy....
Uncheck Remote database and synchronization client leaving Consolidated database and MobiLink server checked and click Next.
Check Save changes to the following SQL file and Connect to the consolidated database to directly apply the changes with NamesCondb selected in the list. Click Next.
Accept the creation of the new directory if prompted.
Enter a MobiLink user and password. Note that MobiLink users are distinct from SQL Anywhere database users. You should use a different username than dba. Suggest 'user' and 'password' respectively. These will be used later in the tutorial.
Ensure that Register this user in the consolidated database for MobiLink authentication is checked and click Finish.
Accept the creation of the new directory if prompted.
Once the deployment window shows the deployment completing, dismiss it by clicking Close.
Now that the synchronization model has been deployed, the consolidated database contains all the information required for MobiLink to function. The deployment also created scripts for launching the MobiLink server:
Open a Terminal.
Navigate the Terminal session to where deployment saved the launch script. By default this should be ~/NamesProject/NamesModel/mlsrv.
Make the script executable:
chmod u+x NamesModel_mlsrv.sh |
Start the MobiLink server:
./NamesModel_mlsrv.sh "DSN=Names" |
You now have a consolidated database with a MobiLink server running. In order for the application to be able to synchronize to it, you first have to enable synchronization. In the openConnection method in the DataAccess class, after the if-block that contains the database creation add the following line:
ULDatabaseManager::EnableTcpipSynchronization(); |
Now that the database is expecting to be synchronized, you can add the following method to the DataAccess class. Also add the method signature to the header file.
- (void)synchronize { NSString * result = nil; ul_sync_info info; // Initialize the sync info struct connection->InitSyncInfo(&info); // Set the sync parameters info.user_name = (char*)"user"; // Set to your username info.password = (char*)"password"; // Set to your password info.version = (char*)"NamesModel"; info.stream = "tcpip"; info.stream_parms = (char*)"host=localhost"; // Display the network activity indicator in the status bar [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; // Sync and get the result if (connection->Synchronize(&info)) { result = @"Sync was successful."; } else { // Get the error message and log it. char errorMsg[80]; connection->GetLastError()->GetString(errorMsg, 80); NSLog(@"Sync failed: %s", errorMsg); result = [NSString stringWithFormat:@"Sync failed: %s", errorMsg]; } // Stop showing the activity indicator [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; [[[[UIAlertView alloc] initWithTitle:@"Synchronization" message:result delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] autorelease] show]; } |
This is the simplest synchronization a client can perform. In an enterprise application, you would likely want to set a callback method to get the progress of the synchronization and perform the synchronization on a separate thread to not block the application.
Also, in the current implementation, synchronization is done on the main event thread. It is not recommended to block the main thread this way. In the next lesson you will use a separate thread to do the synchronization and add a callback method to observe the sync and display the progress.
To let the user choose when to synchronize, add a button to the navigation bar. Pressing the button will call the following method in RootViewController:
- (void)sync { [[DataAccess sharedInstance] synchronize]; [self.tableView reloadData]; } |
To create the button, add the following to the RootViewController's viewDidLoad method:
// Little button with the refresh sign on the left in the nav bar self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(sync)]; |
You can now build and run the application. Whenever you press the refresh button, the database on the iPhone is synchronized with the consolidated SQL Anywhere database.
Discuss this page in DocCommentXchange.
|
Copyright © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |