Today, I published what I solution to the first missing piece:
Allow for offline CouchApp loading since you cannot assume there will be a connection to download a CouchApp
that I hope others will find useful and efficient to use in their day-to-day development workflow.
Workflow
To end up with a nicely packaged couchapp, views, and application seed data, you need to decide what workflow you want to follow during development, testing, release, etc. I chose the following process:
- use source files for everything. I originally tried to edit views in futon, but besides not having source files that could be checked into version control, after the first edit, the web formatting made it difficult to maintain.
- develop and debug on my laptop to take advantage of a full suite of browser developer tools. If you want to get a feel for how difficult directly testing in phonegap can be, take a look at the following post: http://www.phonegap.com/2011/05/18/debugging-phonegap-javascript.
- run on a mobile simulator or hardware periodically after testing on laptop/PC. This should catch device-specific problems and differences after the general problems have been fixed in a more productive laptop/PC development environment.
In order to achieve this result, I am using the following development workflow:
- use soca on my local filesystem to have source files for everything including the couchapp, views, and application seed data.
- use ‘soca autopush’ to propagate any local changes into a couch development server. Note: I added a new flag to soca’s config.js file so until the main branch picks it up (fingers crossed), you will need to use my copy in GitHub.
- use ‘couchpack database_url destination_file —auto’ to watch for and pack all changes into my iOS project’s Resources directory. I wrote the couchpack and couchwatcher gems for this purpose.
- build and run in XCode
- use an Objective-C class called ‘CouchMover’ to check packed version files for changes at runtime and to upload on app launch. I released this class in the phonegap-couchbase-xplatform GitHub repository.
Note: currently, this workflow has only been tested on the Mac OSX platform and does not yet have sample code for an android version. Volunteers are welcome!
Setup details
Install: soca
For now, you’ll need to get a local copy from GitHub and to build/install a local copy:
sudo gem uninstall soca
git clone git@github.com:kmalakoff/soca.git
cd soca
sudo rake install
Install: couchpack
sudo gem install couchpack
Usage - Laptop/PC
I recommend you download the cross-platform demo project at: https://github.com/kmalakoff/phonegap-couchbase-xplatform. It demonstrates the workflow and you won’t be slowed down with setting up a PhoneGap/Couchbase project from scratch.
In the demo project, you will find a file called couch_automate.rb. It demonstrates how you can launch all of the soca and couchpack watching with one command ‘ruby couch_automate.rb’. Here’s the meaningful parts:
exec 'cd soca/mycouchapp; soca autopush'
exec 'cd phonegap-couchbase-ios/phonegap-couchbase-ios/Resources;
couchpack document http://localhost:5984/mycouchapp_db/_design/mycouchapp
mycouchapp --auto'
The first line starts watching the soca project and pushes changes into the couchdb document; the second line starts watching the couchdb document and packs any changes into the iOS Xcode project Resources directory.
Usage - Objective-C
When you receive the CouchbaseDelegate’s method callback couchbaseDidStart you can use the CouchMover class to check for version changes in your packed Resources and if there are changes, upload them to the iOS Couchbase CouchDB using the following:
NSURLCredential *credential = [NSURLCredential credentialWithUser:@"admin"
password:@"admin" persistence:NSURLCredentialPersistenceForSession];
CouchMover* couchMover = [[CouchMover alloc] init:serverURL
serverCredential:credential databaseName:@"mycouchapp_db"];
[couchMover loadDocumentFromBundle:[NSBundle mainBundle]
documentName:@"_design/mycouchapp"
documentBundlePath:@"mycouchapp.json"
versionBundlePath:@"mycouchapp.version"];
[couchMover gotoAppPage:@"_design/mycouchapp" webView:self.webView
page:@"index.html"];
[couchMover release];
The CouchMover class is flexible enough to upload documents which can be packaged couchapps, views, or application seed data to any database (just call ‘[couchMover setDatabaseName:@”yourdatadatabasename”]’ to switch databases) and can be used without the bundles if you prefer (just call ‘[couchMover loadDocument:documentName version:version getAppAsJSONDataBlock:yourblock_returningNSData]’)
Gotchas
There are many and I’ll maintain this list based on your feedback:
- To get the sample running on actual hardware, you’ll need to register the app with Apple using these PhoneGap instructions: http://wiki.phonegap.com/w/page/39991939/Getting-Started-with-PhoneGap-iOS-using-Xcode-4-(Template-Version
- After you pack your couchdb documents for the first time, you need to drag them into your XCode project’s Resources directory.
- In order to not have your PhoneApp switch to the local Safari app when you call [webView stringByEvaluatingJavaScriptFromString:couchappApgeURL], you need to add localhost to the ExternalHosts key in your PhoneGap.plist. Select your PhoneGap.plist in the “Supporting Files” directory, and add the following 2 items as separate entries: 127.0.0.1 and 0.0.0.0.
- The CouchMover Objective-C class current has dependencies on TouchFoundation’s classes on NSData asBase64EncodedString. If you aren’t linking with TouchFoundation, include the files that you find in the sample project’s Vendor/TouchFoundation_MinimalExtraction in your project.
Done! Well, if only reality were that simple… I’m happy to update this post and answer your questions as you are confronted with real-world problems in getting this to work.
Good luck!
Kevin