Streets Ahead

Presents

Interesting Stuff

A Very Brief Intro to CouchDB on iOS

I wanted to get this post out today so it is a little lighter than I wanted, but soon I am going to create a post that shows a cool implementation built using this and the code from my previous CouchDB post. So todays post covers the very basics of using CouchDB on the iPhone. Let me be clear, we're not calling a remote Couch server from the iPhone, we're actually running a local CouchDB server on the iPhone, which is pretty cool.

Why would anyone want to do this?

To me the most useful reason to run Couch on the iPhone is because Couch is awesome at syncing. Now we can write all the data we want to our local Couch and it doesn't matter if we're connected or not. Then once we get connected we can do a quick sync and boom we have offline apps. More details on setting up CouchDB on the iPhone can be found on the couchbase.org site. For a quick overview there are two pieces we'll be using, the first is the Couchbase for iOS framework, this is the actual native Couch implementation for iOS, the other piece is the CouchCocoa framework. The CouchCocoa framework is a framework for accessing CouchDB from Mac or iOS apps. The CouchCocoa framework is composed of a collection of classes that implement basic REST operations that utilize NSURLRequest and a collection of classes that implement CouchDB objects such as CouchServer, CouchDatabase, and CouchDocument.

Without further ado...

Implement the CouchbaseDelegate:

- (BOOL)application:(UIApplication *)application 
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    CouchbaseMobile* cb = [[CouchbaseMobile alloc] init];
    cb.delegate = self;

    NSAssert([cb start], @"Couchbase didn't start! Error = %@", cb.error);

    return YES;
}

This code is relatively simple we're just allocating a new instance of Couchbase Mobile, setting the delegate and starting it up. In this case my delegate is my app's delegate.

Now we can write a little code to create a database and a document, we do this in the couchbaseMobile:didStart method because we need to be sure that our DB has started:

- (void)couchbaseMobile:(CouchbaseMobile *)couchbase didStart:(NSURL *)serverURL {
    NSLog(@"CouchDB is started");

    CouchServer* server = [[CouchServer alloc] initWithURL:serverURL];
    CouchDatabase* db = [server databaseNamed:@"mydb"];

    // make asynchronous call using block
    RESTOperation* op = [db create];
    [op onCompletion:^{
        NSLog(@"DB CREATED FOOL!");
        [self createDocumentInDatabase:db];
    }];
    [op start];
}

- (void)createDocumentInDatabase:(CouchDatabase*)db {
    CouchDocument* doc = [db untitledDocument];
    RESTOperation* op = [doc putProperties:[NSDictionary dictionaryWithObjectsAndKeys:
                        @"Women Be", @"mykey1",
                        @"Stoppin", @"mykey2", nil]];

    // make a synchronous call
    BOOL wasCreated = [op wait];
    NSLog(@"DOCUMENT CREATED PLAYA %d", wasCreated);
}

Just incase something goes wrong you should probably implement this delegate method as well:

- (void)couchbaseMobile:(CouchbaseMobile *)couchbase failedToStart:(NSError *)error {
    NSLog(@"An error occurred, %@", [error localizedDescription]);
}

Now we can run our app and test out our embedded DB. Once our DB is started we can confirm by hitting the Couch server from our browser, the addresses that Couch is running on should appear in your Xcode console output mine is http://127.0.0.1:53304. Your browser should show something like this:

{
    "couchdb":
    "Welcome",
    "version":
    "2.0.0-beta"
}

We can list all the databases using this url:

http://127.0.0.1:53304/alldbs

[
    "_replicator",
    "_users",
    "mydb",
    "test"
]

We can list all documents in a DB using this one:

http://127.0.0.1:53304/mydb/alldocs

{
    "offset":0,
    "rows":
    [
        {
            "id":"32f34b65638b7da44ff828e0890009bb",
            "key":"32f34b65638b7da44ff828e0890009bb",
            "value":
            {
                "rev":"1-51cf9d99c543abd4f59321a737180fb1"
            }
        }
    ],
    "total_rows":1
}

And once we know what our document ID is we can check out our document this way:

http://127.0.0.1:53304/mydb/32f34b65638b7da44ff828e0890009bb

{
    "_id":"32f34b65638b7da44ff828e0890009bb",
    "_rev":"1-51cf9d99c543abd4f59321a737180fb1",
    "mykey1":"Women Be",
    "mykey2":"Stoppin"
}

That's pretty much it for tonight. You can grab my Xcode project from GitHub. I built this using the latest release of Xcode (4.2) from the App Store on OS X Lion and iOS simulator 5.0, if you have a different setup the code should still work but you may have to tweak some settings. Thanks once again for reading, sorry for the light post, but expect something cool to come.

Links

blog comments powered by Disqus