Paul Roub

A Software Tool Geek in His Natural Habitat

Using Zumero for SQL Server With FMDB and SQLCipher

Recently, I described how to use SQLCipher with Zumero to encrypt your locally-synched DBfiles. That was all fine, except:

  1. This was before the advent of Zumero for SQL Server.
  2. The ZSS framework includes a stripped-down, synch-only object model, allowing you to use your iOS SQLite wrapper of choice (I choose FMDB)
  3. There’s a lot of “install this”, “drag this to that”, “install the other thing”… Tedious to describe, tedious to follow.

These days, the smart and sane are using Cocoapods to manage the components they’re using in their Xcode projects. There’s a pod for FMDB, one for SQLCipher and now, a Zumero for SQL Server Cocoapod.

How do we combine all the pieces? Head to your XCode iOS project’s folder, and make sure you have a Podfile. In that Podfile, mention Zumero and FMDB, using the SQLCipher variants of both pods:

platform :ios, '7.0'
pod 'ZumeroSync/SQLCipher'
pod 'FMDB/SQLCipher'

No need to specify SQLCipher itself — it’s already noted as a dependency in both the Zumero and FMDB pods.

Now run pod install (or pod update if other pods are already in place):

$ pod install
Analyzing dependencies
Downloading dependencies
Installing FMDB (2.1)
Installing SQLCipher (2.1.1)
Installing ZumeroSync (1.0.0.1556)
Generating Pods project
Integrating client project

[!] From now on use `EncryptedDBApp.xcworkspace`.

Do as the nice program says, and open the workspace it’s created for you.

Look! Pods!

FMDB, SQLCipher, and Zumero pods installed in project

Include paths are all taken care of:

autocomplete on Zumero inclusion

As for actually using the three?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// you'll think harder about this
NSString *dbpath = @"/tmp/foo.db";

// creates the local database, if needed
FMDatabase *db = [FMDatabase databaseWithPath:dbpath];

NSString *key = @"shhhh! secret!";
[db setKey:key];

// No networking on the UI thread. Your app thanks you.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSError *err = nil;

    // synch local/remote changes
    // initialize the local db if needed
    BOOL ok = [ZumeroSync Sync:dbpath
                     cipherKey:key
                     serverUrl:@"https://myserver.example.com"
                        remote:@"remoteFoo"
                    authScheme:nil
                          user:nil  // again, you'll think harder
                      password:nil
                         error:&err];

    if (ok)
    {
        ok = [db open];
        // and off you go
    }
});

Easy to blog, easy to follow.

Comments