couchbase mobile 101: how to build your first mobile app with couchbase mobile: couchbase connect...

56
COUCHBASE MOBILE 101 Jens Alfke Mobile Architect Couchbase, Inc.

Upload: couchbase

Post on 26-Jul-2015

257 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

COUCHBASE MOBILE 101

Jens AlfkeMobile ArchitectCouchbase, Inc.

Jens Alfke
NOTE: This presentation uses the “FontAwesome” font. Download from http://fortawesome.github.io and install FontAwesome.otf.
Page 2: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

A Whirlwind 45 Minutes

Couchbase Mobile featuresFocus on Couchbase Lite:Installing and running a sample appA tour of Couchbase Lite’s architecture and API…as shown in the sample app’s code

Next steps

Page 3: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

What Is Couchbase Mobile?Couchbase LiteClient database libraryFor mobile or desktop apps

Couchbase Sync GatewayApp serverFront-end for Couchbase Server

Page 4: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

What Makes Couchbase Mobile Awesome?

ReplicationTransparent availability of data on server &

clientFull offline functionality

Data orchestrationSmart routing of data to its usersSubsetting data sets for different use cases

Page 5: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

Couchbase Sync Gateway…will be introduced in Couchbase Mobile 102

at 1:45pm

Page 6: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

Couchbase Lite…will be introduced almost immediately

Page 7: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Couchbase Lite

Embedded database library for mobile appsFlexible, schemaless data model (“NoSQL”)Querying by map/reduce viewsActive change notifications, for reactive UIsFull-strength multi-master replication

Page 8: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Couchbase Mobile Replication

Avoid network latency for data accessOffline support (if you want it)Control over conflict resolutionArbitrary topologies, including P2POpen protocol

Page 9: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

Running Your First App

Page 10: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Running Your First iOS App

Install Xcode 6 from Mac App StoreDownload Couchbase LiteDownload Grocery Sync sample codeCopy framework into sample app folderBuild & Run the Xcode project

Page 11: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

2. Download Couchbase Lite

couchbase.com/nosql-databases/downloadsClick “Couchbase Mobile”

Page 12: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

3. Download Grocery Sync Source Codegithub.com/couchbaselabs/Grocery-Sync-iOS

Page 13: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

4. Plug In The Framework

option

Page 14: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

5. Open The Project

Page 15: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Running Your First Android AppInstall Android Studio with Android SDK 19 &

Build Tool 19Check out Grocery Sync sample code repoImport Grocery Sync gradle file into Android

StudioPress Debug or Run button

Page 16: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

2. Download Grocery Sync Source Code

Page 17: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

3. Import ‘build.gradle’ into Android Studio

Page 18: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

Quick Demo

Page 19: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

A Tour Of The CodeAnd The API

in large friendly letters

Page 20: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

1. Initialization & Insertion

Page 21: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

InitializationDemoAppDelegate.m:61

// Initialize Couchbase Lite and find/create my database: NSError* error; self.database = [[CBLManager sharedInstance] databaseNamed: kDatabaseName error: &error]; if (!self.database) { [self showAlert: @"Couldn't open database" error: error fatal: YES]; return NO; }

Page 22: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

InitializationMainActivity.java:118

manager = new Manager(new AndroidContext(this), Manager.DEFAULT_OPTIONS);

database = manager.getDatabase(DATABASE_NAME);

Page 23: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Manager

Top-level object, usually a singletonA collection of named databasesLocates databases in filesystem

Page 24: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Databases And Documents

Databas

e“to-do”

“doc1”

“doc2”

“doc3”

Document “doc2”{ “text”: “Vacuum kitchen”, “created”: “2015-05–28”, “check”: false, “tags”: [“jens”, “chore”]}

thumb.jpg

Page 25: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Database

Namespace for documentsContains views and their indexesContains validation functionsSource and target of replication

Page 26: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Document“_id” is unique within database, immutableJSON allows nested data structures (arrays,

maps)Schemaless — Documents needn’t have the

same structureDifferent types of docs can coexist in a

database“type” property is a common convention

Documents are versionedOptimistic concurrency control (MVCC)

Page 27: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Adding New ItemsRootViewController.m:243

// Create the new document's properties: NSDictionary *document = @{@"text": text, @"check": @NO, @"created_at": [CBLJSON JSONObjectWithDate: [NSDate date]]}; // Save the document: CBLDocument* doc = [database createDocument]; NSError* error; if (![doc putProperties: document error: &error]) { [self showErrorAlert: @"Couldn't save new item" forError: error]; }

Page 28: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Adding New ItemsMainActivity.java:343

SimpleDateFormat dateFormatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); UUID uuid = UUID.randomUUID(); Calendar calendar = GregorianCalendar.getInstance(); long currentTime = calendar.getTimeInMillis(); String currentTimeString = dateFormatter.format(calendar.getTime()); String id = currentTime + "-" + uuid.toString();

Document document = database.createDocument(); Map<String, Object> properties = new HashMap<String, Object>(); properties.put("_id", id); properties.put("text", text); properties.put("check", Boolean.FALSE); properties.put("created_at", currentTimeString);

document.putProperties(properties);

Page 29: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

2. Views & Queries

Page 30: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Creating A Database ViewRootViewController.m:101

// Define a view with a map function that indexes to-do items by creation date: [[theDatabase viewNamed: @"byDate"] setMapBlock: MAPBLOCK({ id date = doc[@"created_at"]; if (date) emit(date, nil); }) version: @"1.1"];

Not a UIView —a database “view”is like an index.

Page 31: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Map/Reduce Views

Concept from functional programming, via Google

App-defined map function operates on documentsdoc ⟼ { (key, value) …}

Its output generates an index ordered by keyIndex rows can be aggregated by a reduce

functionIndex is queried by key or key range

Page 32: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Map/Reduce Indexing

emit(doc.created, doc.title)

key value docID

“2013-03-12”

“taxes” “doc17”

“2013-09-30”

“call mom”

“doc62”

“2013-10-17”

“cat food” “doc82”

“2013-10-17”

“tea bags”

“doc83”

“2013-10-22”

“upgrade” “doc90”

index

all d

ocu

ments

map function

View“byDate”

Page 33: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Creating A Database ViewRootViewController.m:101

// Define a view with a map function that indexes to-do items by creation date: [[theDatabase viewNamed: @"byDate"] setMapBlock: MAPBLOCK({ id date = doc[@"created_at"]; if (date) emit(date, nil); }) version: @"1.1"];

Not a UIView —a database “view”is like an index.

Page 34: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Creating A Database ViewMainActivity.java:122

com.couchbase.lite.View viewItemsByDate = database.getView(String.format("%s/%s", designDocName, byDateViewName)); viewItemsByDate.setMap(new Mapper() { @Override public void map(Map<String, Object> document, Emitter emitter) { Object createdAt = document.get("created_at"); if (createdAt != null) { emitter.emit(createdAt.toString(), null); } } }, "1.0");

Not a UIView —a database “view”is like an index.

Page 35: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Driving the Table from a View QueryRootViewController.m:101

// Create a query sorted by descending date, i.e. newest items first: CBLLiveQuery* query = [[[database viewNamed:@"byDate"] query] asLiveQuery]; query.descending = YES;

// Plug the query into the CBLUITableSource, which uses it to drive the table. // (The CBLUITableSource uses KVO to observe the query's .rows property.) self.dataSource.query = query; self.dataSource.labelProperty = @"text";

@property(nonatomic, strong) IBOutlet UITableView *tableView;@property(nonatomic, strong) IBOutlet CBLUITableSource* dataSource;

RootViewController.h:41

Page 36: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Driving the Table from a View QueryRootViewController.m:101

liveQuery = view.createQuery().toLiveQuery();

liveQuery.addChangeListener(new LiveQuery.ChangeListener() { public void changed(final LiveQuery.ChangeEvent event) { runOnUiThread(new Runnable() { public void run() { grocerySyncArrayAdapter.clear(); for (Iterator<QueryRow> it = event.getRows(); it.hasNext();) { grocerySyncArrayAdapter.add(it.next()); } grocerySyncArrayAdapter.notifyDataSetChanged();

Page 37: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

LiveQuery

Querying a View

key value docID

“2013-03-12”

“taxes” “doc17”

“2013-09-30”

“call mom”

“doc62”

“2013-10-17”

“cat food” “doc82”

“2013-10-17”

“tea bags”

“doc83”

“2013-10-22”

“upgrade” “doc90”

index

} Query QueryRowQueryRow

QueryRow

.limit = 3

.offset = …

.reverse = …

.startKey = …

.endKey = …

Page 38: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

LiveQuery Driving An iOS UITableView

LiveQuery

QueryCBLUITable-Source

UITableView

Your Controller

data source

delegate

Page 39: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

LiveQuery Driving An iOS UITableView

Page 40: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Displaying Table CellsDemoAppDelegate.m:131

- (void)couchTableSource:(CBLUITableSource*)source willUseCell:(UITableViewCell*)cell forRow:(CBLQueryRow*)row{ // Set the cell background and font: ……… // Configure the cell contents. Map function (above) copies the doc properties // into its value, so we can read them without having to load the document. NSDictionary* rowValue = row.value; BOOL checked = [rowValue[@"check"] boolValue]; if (checked) { cell.textLabel.textColor = [UIColor grayColor]; cell.imageView.image = [UIImage imageNamed:@"checked"]; } else { cell.textLabel.textColor = [UIColor blackColor]; cell.imageView.image = [UIImage imageNamed: @"unchecked"]; } // cell.textLabel.text is already set, thanks to setting up labelProperty}

Called by the CBLUITableSource when it’s told to display a cell.

Page 41: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Displaying Table CellsGrocerySyncArrayAdapter.java:33

public View getView(int position, View itemView, ViewGroup parent) {//...TextView label = ((ViewHolder)itemView.getTag()).label;QueryRow row = getItem(position);SavedRevision currentRevision = row.getDocument().getCurrentRevision();// Check boxObject check = (Object) currentRevision.getProperty("check");boolean isGroceryItemChecked = false;if (check != null && check instanceof Boolean) isGroceryItemChecked = ((Boolean)check).booleanValue();// TextString groceryItemText = (String) currentRevision.getProperty("text");label.setText(groceryItemText);

Page 42: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Responding To TapsDemoAppDelegate.m:131

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // Ask CBLUITableSource for the corresponding query row, and get its document: CBLQueryRow *row = [self.dataSource rowAtIndex:indexPath.row]; CBLDocument *doc = row.document;

// Toggle the document's 'checked' property: NSMutableDictionary *docContent = [doc.properties mutableCopy]; BOOL wasChecked = [docContent[@"check"] boolValue]; docContent[@"check"] = @(!wasChecked);

// Save changes: NSError* error; if (![doc.currentRevision putProperties: docContent error: &error]) { [self showErrorAlert: @"Failed to update item" forError: error]; }}

Called by the UITableView itself

Page 43: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Responding To TapsMainActivity.java:243

public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { QueryRow row = (QueryRow) adapterView.getItemAtPosition(position); Document document = row.getDocument(); Map<String, Object> newProperties = new HashMap<String, Object>(document.getProperties());

boolean checked = ((Boolean) newProperties.get("check")).booleanValue(); newProperties.put("check", !checked);

try { document.putProperties(newProperties); grocerySyncArrayAdapter.notifyDataSetChanged(); } catch (Exception e) { // ...

Page 44: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Change Notifications

Three types:DatabaseChanged: Any document updatedDocumentChanged: A specific document

updatedLiveQuery: Change in query result set

Enables reactive programming

ControllerModel

(Database)GUI View

User event Update doc

DocumentChanged

Redraw

Replication(pull)

Page 45: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

3. Replication

Page 46: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Replication

Replicatio

n(push)

Replication

(pull) https://exam.pl/db

local_db

Page 47: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Replication

Replication is asynchronousUse database notifications to detect changes

A Replication can be one-shot or continuousOne-shot runs only until it “catches up”Continuous keeps going till stopped or app

quitsContinuous handles online/offline transitions

gracefullyReplications can be filtered

Page 48: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Creating ReplicationsDemoAppDelegate.m:74

_pull = [database createPullReplication: serverDbURL]; _push = [database createPushReplication: serverDbURL]; _pull.continuous = _push.continuous = YES; // Observe replication progress changes, in both directions: NSNotificationCenter* nctr = [NSNotificationCenter defaultCenter]; [nctr addObserver: self selector: @selector(replicationProgress:) name: kCBLReplicationChangeNotification object: _pull]; [nctr addObserver: self selector: @selector(replicationProgress:) name: kCBLReplicationChangeNotification object: _push]; [_push start]; [_pull start];

Page 49: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Creating ReplicationsMainActivity.java:150

Replication pullReplication = database.createPullReplication(syncUrl); pullReplication.setContinuous(true);

Replication pushReplication = database.createPushReplication(syncUrl); pushReplication.setContinuous(true);

pullReplication.start(); pushReplication.start();

pullReplication.addChangeListener(this); pushReplication.addChangeListener(this);

Page 50: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Monitoring ReplicationsDemoAppDelegate.m:98

- (void) replicationProgress: (NSNotificationCenter*)n { if (_pull.status == kCBLReplicationActive || _push.status == kCBLReplicationActive) { // Sync is active -- aggregate the progress of both replications and compute a fraction: unsigned completed = _pull.completedChangesCount + _push.completedChangesCount; unsigned total = _pull.changesCount+ _push.changesCount; NSLog(@"SYNC progress: %u / %u", completed, total); // Update the progress bar, avoiding divide-by-zero exceptions: [self.rootViewController showSyncStatus: (completed / (float)MAX(total, 1u))]; } else { // Sync is idle -- hide the progress bar and show the config button: NSLog(@"SYNC idle"); [self.rootViewController hideSyncStatus]; }

// Check for any change in error status and display new errors: NSError* error = _pull.lastError ? _pull.lastError : _push.lastError; if (error != _syncError) { _syncError = error; if (error) { [self showAlert: @"Error syncing" error: error fatal: NO]; } }}

Page 51: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Monitoring ReplicationsMainActivity.java:381

public void changed(Replication.ChangeEvent event) { Replication replication = event.getSource(); Log.d(TAG, "Replication : " + replication + " changed."); if (!replication.isRunning()) { String msg = String.format("Replicator %s not running", replication); Log.d(TAG, msg); } else { int processed = replication.getCompletedChangesCount(); int total = replication.getChangesCount(); String msg = String.format("Replicator processed %d / %d", processed, total); Log.d(TAG, msg); } if (event.getError() != null) { showError("Sync error", event.getError()); } }

Page 52: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

Whew!(we’re done now)

Page 53: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

Next Steps

Page 54: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Next Sessions1:45–2:30 — #102: Sync Gateway3:45–4:30 — #103: Peer-to-Peer Sync5:15–6:00 — #104: Mobile Games with Unity

Page 55: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

©2015 Couchbase Inc.

Next Steps

Try connecting Grocery Sync to your own Sync Gateway

RTFM!Look at other sample apps:ToDo LiteCouchbase Connect Conference app (

.NET/Xamarin)Visit our mobile developer forums

Page 56: Couchbase Mobile 101: How to Build Your First Mobile App with Couchbase Mobile: Couchbase Connect 2015

The End — Any Questions?