Thursday, June 11, 2015

Mobile workshop: Couchbase lite in-depth

Mobile workshop: Couchbase lite in-depth



Mobile workshop: Couchbase lite in-depth from Couchbase
This daylong workshop will feature a combination of lecture and hands-on lab training on Couchbase Mobile, the embeddable JSON database with built-in sync for Android, iOS, Xamarin and Unity. During this workshop, we will take Android and iOS developers through everything you need to know to get started working with Couchbase Mobile.
Published in: Technology

Transcript

  • 1. COUCHBASE  LITE  IN-­‐DEPTH James  Nocentini,   Developer  Advocate,   Couchbase
  • 2. ©2014  Couchbase  Inc. This  morning ▪ Using  Documents  and  Revisions   ▪ Utilising  convenience  Data  Model  APIs   ▪ Creating  Couchbase  Lite  Views   ▪ Querying  Views   ▪ Live  Queries 2
  • 3. ToDo  Lite
  • 4. ©2014  Couchbase  Inc. 4
  • 5. Demo
  • 6. ©2014  Couchbase  Inc. Data  Model   6
  • 7. ©2014  Couchbase  Inc. 7©2015&Couchbase&Inc. Overview ▪ Couchbase&Mobile&features& ▪ Focus&on&Couchbase&Lite:& ▪ Installing&and&running&a&sample&app& ▪ A&tour&of&Couchbase&Lite’s&architecture&and&API& ▪ …as&shown&in&the&sample&app’s&code& ▪ Next&steps 2
  • 8. 1.  Database
  • 9. ©2014  Couchbase  Inc. 9©2015&Couchbase&Inc. Initialization DemoAppDelegate.m:61 !!!!//"Initialize"Couchbase"Lite"and"find/create"my"database:! !!!!NSError*!error;! !!!!self.database!=![[CBLManager!sharedInstance]!createDatabaseNamed:!kDatabaseName! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!error:!&error];! !!!!if!(!self.database)!{! !!!!!!!![self!showAlert:!@"Couldn't!open!database"!error:!error!fatal:!YES];! !!!!!!!!return!NO;! !!!!}! 18
  • 10. ©2014  Couchbase  Inc. Database 10 public class Application extends android.app.Application { @Override
 public void onCreate() {
 super.onCreate();
 
 
 
 } }
  • 11. ©2014  Couchbase  Inc. Database 11 public class Application extends android.app.Application { @Override
 public void onCreate() {
 super.onCreate();
 
 Manager manager = new Manager(new AndroidContext(getApplicationContext()), Manager.DEFAULT_OPTIONS);
 
 } }
  • 12. ©2014  Couchbase  Inc. Database 12 public class Application extends android.app.Application { @Override
 public void onCreate() {
 super.onCreate();
 
 Manager manager = new Manager(new AndroidContext(getApplicationContext()), Manager.DEFAULT_OPTIONS);
 Database database = manager.getDatabase("dbname");
 } }
  • 13. ©2014  Couchbase  Inc. 13©2015&Couchbase&Inc. Manager ▪ TopJlevel&object,&usually&a&singleton& ▪ A&collection&of&named&databases& ▪ Locates&databases&in&filesystem 19
  • 14. ©2014  Couchbase  Inc. 14©2015&Couchbase&Inc. Database ▪ Namespace&for&documents& ▪ Contains&views&and&their&indexes& ▪ Contains&validation&functions& ▪ Source&and&target&of&replication 21
  • 15. ©2014  Couchbase  Inc. Database 15
  • 16. ©2014  Couchbase  Inc. 16©2015&Couchbase&Inc. Interesting+Document+Facts ▪ JSON&allows&nested&data&structures&(arrays,&maps)& ▪ Schemaless&—&Documents&needn’t&have&the&same&structure& ▪ Different&types&of&docs&can&coexist&in&a&database& ▪ “type”&property&is&a&common&convention& ▪ Documents&are&versioned& ▪ Optimistic&concurrency&control&(MVCC) 22
  • 17. ©2014  Couchbase  Inc. Documents 17 Map<String, Object> properties = new HashMap<String, Object>();
 properties.put("type", "list");
 properties.put("title", title);
 properties.put("created_at", currentTimeString);
 properties.put("owner", "profile:" + userId);
 properties.put("members", new ArrayList<String>()); 
 

  • 18. ©2014  Couchbase  Inc. Documents 18 Map<String, Object> properties = new HashMap<String, Object>();
 properties.put("type", "list");
 properties.put("title", title);
 properties.put("created_at", currentTimeString);
 properties.put("owner", "profile:" + userId);
 properties.put("members", new ArrayList<String>()); 
 Document document = database.createDocument();

  • 19. ©2014  Couchbase  Inc. Documents 19 Map<String, Object> properties = new HashMap<String, Object>();
 properties.put("type", "list");
 properties.put("title", title);
 properties.put("created_at", currentTimeString);
 properties.put("owner", "profile:" + userId);
 properties.put("members", new ArrayList<String>()); 
 Document document = database.createDocument();
 document.putProperties(properties);
  • 20. ©2014  Couchbase  Inc. Documents 20 Document document = database.getDocument("task-123");
 
 
 
 

  • 21. ©2014  Couchbase  Inc. Documents 21 Document document = database.getDocument("task-123");
 
 String title = document.getProperty("title");
 
 

  • 22. ©2014  Couchbase  Inc. Documents 22 Document document = database.getDocument("task-123");
 
 String title = document.getProperty("title");
 
 Map<String, Object> properties = doc.getProperties();
 String owner = (String) properties.get("owner");
  • 23. ©2014  Couchbase  Inc. Documents { "_id": "123", "type": "list", "title": "Today’s list", "owner": "1234567890", "members": [ "0987654321", "0192837465" ] } 23
  • 24. Models
  • 25. ©2014  Couchbase  Inc. Models 25 @interface Task : CBLModel @end @implementation Task @end
  • 26. ©2014  Couchbase  Inc. Models 26 @interface Task : CBLModel @property NSString *title; @end @implementation Task @dynamic title; @end
  • 27. ©2014  Couchbase  Inc. Models 27 @interface Task : CBLModel @property NSString *title; @property bool checked; @end @implementation Task @dynamic title, checked; @end
  • 28. ©2014  Couchbase  Inc. Models 28 @interface Task : CBLModel @property NSString *title; @property bool checked; @property (weak) List *list_id; @end @implementation Task @dynamic title, checked, list_id; @end
  • 29. ©2014  Couchbase  Inc. Models 29 Task *task = [Task modelForNewDocumentInDatabase:self.database]; New  model New  model  for   Saving  the  model [task save:nil]; Task *task = [Task modelForDocument:self.database];
  • 30. ©2015  Couchbase  Inc. ‹#›
  • 31. ©2014  Couchbase  Inc. 31 2.+Views+&+Queries
  • 32. ©2014  Couchbase  Inc. 32©2015&Couchbase&Inc. Creating+A+Database+View RootViewController.m:50 !!!!//"Define"a"view"with"a"map"function"that"indexes"toAdo"items"by"creation"date:! !!!![[theDatabase!viewNamed:!@"byDate"]!setMapBlock:!MAPBLOCK({! !!!!!!!!id!date!=!doc[@"created_at"];! !!!!!!!!if!(date)! !!!!!!!!!!!!emit(date,!doc);! !!!!})!version:!@"1.1"];! Not a UIView —a database “view”is like an index. 25
  • 33. ©2014  Couchbase  Inc. 33©2015&Couchbase&Inc. Map/Reduce+Views ▪ Concept&from&functional&programming,&via&Google& ▪ AppJdefined&map+function&operates&on&documents& ▪ doc&&⟼&&{&(key,&value)&…}& ▪ Its&output&generates&an&index&ordered&by&key& ▪ Index&rows&can&be&aggregated&by&a&reduce+function+ ▪ Index&is&queried&by&key&or&key&range 26
  • 34. ©2014  Couchbase  Inc. 34©2015&Couchbase&Inc. Map/Reduce+Indexing emit(doc.created,! !!!!!doc.title) key value docID “2013D03D12” “taxes” “doc17” “2013D09D30” “call)mom” “doc62” “2013D10D17” “cat)food” “doc82” “2013D10D17” “tea)bags” “doc83” “2013D10D22” “upgrade” “doc90” index alldocuments map function View+ “byDate” 27
  • 35. ©2014  Couchbase  Inc. 35©2015&Couchbase&Inc. Creating+A+Database+View RootViewController.m:101 !!!!//"Define"a"view"with"a"map"function"that"indexes"toAdo"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. 28
  • 36. ©2014  Couchbase  Inc. 36©2015&Couchbase&Inc. Driving+the+Table+from+a+View+Query RootViewController.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 29
  • 37. ©2014  Couchbase  Inc. 37©2015&Couchbase&Inc. LiveQuery Querying+a+View 30 key value docID “2013D03D12” “taxes” “doc17” “2013D09D30” “call)mom” “doc62” “2013D10D17” “cat)food” “doc82” “2013D10D17” “tea)bags” “doc83” “2013D10D22” “upgrade” “doc90” index } Query QueryRow QueryRow QueryRow .limit&=&3& .offset&=&…& .reverse&=&…& .startKey&=&…& .endKey&=&… 
  • 38. ©2014  Couchbase  Inc. 38©2015&Couchbase&Inc. LiveQuery+Driving+A+GUI+Table 31 LiveQuery Query CBLUITableN Source UITableView Your+ Controller data source delegate Note:&CBLUITableSource&is&iOSJonly
  • 39. ©2014  Couchbase  Inc. 39©2015&Couchbase&Inc. LiveQuery+Driving+A+GUI+Table 32
  • 40. ©2014  Couchbase  Inc. 40©2015&Couchbase&Inc. Driving+the+Table+from+a+View+Query RootViewController.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 33
  • 41. ©2014  Couchbase  Inc. 41©2015&Couchbase&Inc. Displaying+Table+Cells DemoAppDelegate.m:131 W!(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! } 34 Called by theCBLUITableSourcewhen it’s told todisplay a cell.
  • 42. ©2014  Couchbase  Inc. 42©2015&Couchbase&Inc. Responding+To+Taps DemoAppDelegate.m:131 W!(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];! !!!!}! }! 35 Called by theUITableView itself
  • 43. ©2014  Couchbase  Inc. 43©2015&Couchbase&Inc. Change+Notifications ▪ Three&types:& ▪ DatabaseChanged:&Any&document&updated& ▪ DocumentChanged:&A&specific&document&updated& ▪ LiveQuery:&Change&in&query&result&set& ▪ Enables&reactive&programming Controller Model& (Database) GUI&View User&event Update&doc DocumentChangedRedraw 36
  • 44. Index
  • 45. ©2014  Couchbase  Inc. Map/Reduce  Index 45 @interface List : CBLModel @property NSString *title; + (CBLQuery*) queryListsInDatabase: (CBLDatabase*)db; @end @implementation Task @dynamic title; + (CBLQuery*) queryListsInDatabase: (CBLDatabase*)db { // ... } @end
  • 46. ©2014  Couchbase  Inc. Map/Reduce  Index 46 + (CBLQuery*) queryListsInDatabase: (CBLDatabase*)db { }
  • 47. ©2014  Couchbase  Inc. Map/Reduce  Index 47 + (CBLQuery*) queryListsInDatabase: (CBLDatabase*)db { CBLView* view = [db viewNamed: @"lists"]; if (!view.mapBlock) { } return [view createQuery]; }
  • 48. ©2014  Couchbase  Inc. Map/Reduce  Index 48 + (CBLQuery*) queryListsInDatabase: (CBLDatabase*)db { CBLView* view = [db viewNamed: @"lists"]; if (!view.mapBlock) { [view setMapBlock: MAPBLOCK({ }) reduceBlock: nil version: @"1"]; } return [view createQuery]; }
  • 49. ©2014  Couchbase  Inc. Map/Reduce  Index 49 + (CBLQuery*) queryListsInDatabase: (CBLDatabase*)db { CBLView* view = [db viewNamed: @"lists"]; if (!view.mapBlock) { [view setMapBlock: MAPBLOCK({ if ([doc[@"type"] isEqualToString:@"list"]) emit(doc[@"title"], nil); }) reduceBlock: nil version: @"1"]; } return [view createQuery]; }
  • 50. ©2014  Couchbase  Inc. Map/Reduce  Index 50 - (CBLQuery*) queryTasks { CBLView* view = [self.document.database viewNamed: @"tasksByDate"]; if (!view.mapBlock) { [view setMapBlock: MAPBLOCK({ if ([doc[@"type"] isEqualToString: @"task"]) { } }) reduceBlock: nil version: @"4"]; } CBLQuery* query = [view createQuery]; return query; }
  • 51. ©2014  Couchbase  Inc. Map/Reduce  Index 51 - (CBLQuery*) queryTasks { CBLView* view = [self.document.database viewNamed: @"tasksByDate"]; if (!view.mapBlock) { [view setMapBlock: MAPBLOCK({ if ([doc[@"type"] isEqualToString: @"task"]) { id date = doc[@"created_at"]; NSString* listID = doc[@"list_id"]; emit(@[listID, date], doc); } }) reduceBlock: nil version: @"4"]; } CBLQuery* query = [view createQuery]; return query; }
  • 52. ©2014  Couchbase  Inc. Map/Reduce  Index 52 - (CBLQuery*) queryTasks { CBLView* view = [self.document.database viewNamed: @"tasksByDate"]; if (!view.mapBlock) { [view setMapBlock: MAPBLOCK({ if ([doc[@"type"] isEqualToString: @"task"]) { id date = doc[@"created_at"]; NSString* listID = doc[@"list_id"]; emit(@[listID, date], doc); } }) reduceBlock: nil version: @"4"]; } CBLQuery* query = [view createQuery]; NSString* listId = self.document.documentID; return query; }
  • 53. ©2014  Couchbase  Inc. Map/Reduce  Index 53 - (CBLQuery*) queryTasks { CBLView* view = [self.document.database viewNamed: @"tasksByDate"]; if (!view.mapBlock) { [view setMapBlock: MAPBLOCK({ if ([doc[@"type"] isEqualToString: @"task"]) { id date = doc[@"created_at"]; NSString* listID = doc[@"list_id"]; emit(@[listID, date], doc); } }) reduceBlock: nil version: @"4"]; } CBLQuery* query = [view createQuery]; NSString* listId = self.document.documentID; query.startKey = @[listId]; query.endKey = @[listId, @{}]; return query; }
  • 54. ©2015  Couchbase  Inc. ‹#›
  • 55. Query
  • 56. ©2014  Couchbase  Inc. Query 56 Query query = database.getView("tasksByDate").createQuery();
 QueryEnumerator result = query.run();
 for (Iterator<QueryRow> it = result; it.hasNext(); ) {
 // do something
 }
  • 57. ©2014  Couchbase  Inc. Query 57 LiveQuery liveQuery = database.getView("tasksByDate").createQuery().toLiveQuery();

  • 58. ©2014  Couchbase  Inc. Query 58 LiveQuery liveQuery = database.getView("tasksByDate").createQuery().toLiveQuery();
 liveQuery.addChangeListener(new LiveQuery.ChangeListener() {
 @Override
 public void changed(LiveQuery.ChangeEvent event) {
 // update the UI
 }
 });
  • 59. ©2014  Couchbase  Inc. Query 59
  • 60. ©2015  Couchbase  Inc. ‹#›
  • 61. Attachments
  • 62. ©2014  Couchbase  Inc. Attachments 62 protected void onActivityResult(int requestCode, int resultCode, Intent data){
 if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
 InputStream stream = getContentResolver().openInputStream(data.getData());
 
 
 
 
 
 }
 }
  • 63. ©2014  Couchbase  Inc. Attachments 63 protected void onActivityResult(int requestCode, int resultCode, Intent data){
 if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
 InputStream stream = getContentResolver().openInputStream(data.getData());
 
 Document document = database.getDocument("task-123"); 
 
 
 
 }
 }
  • 64. ©2014  Couchbase  Inc. Attachments 64 protected void onActivityResult(int requestCode, int resultCode, Intent data){
 if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
 InputStream stream = getContentResolver().openInputStream(data.getData());
 
 Document document = database.getDocument("task-123"); 
 UnsavedRevision newRevision = document.getCurrentRevision().createRevision();
 
 
 }
 }
  • 65. ©2014  Couchbase  Inc. Attachments 65 protected void onActivityResult(int requestCode, int resultCode, Intent data){
 if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
 InputStream stream = getContentResolver().openInputStream(data.getData());
 
 Document document = database.getDocument("task-123"); 
 UnsavedRevision newRevision = document.getCurrentRevision().createRevision();
 newRevision.setAttachment("photo.jpg", "image/jpeg", stream);
 
 }
 }
  • 66. ©2014  Couchbase  Inc. Attachments 66 protected void onActivityResult(int requestCode, int resultCode, Intent data){
 if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
 InputStream stream = getContentResolver().openInputStream(data.getData());
 
 Document document = database.getDocument("task-123"); 
 UnsavedRevision newRevision = document.getCurrentRevision().createRevision();
 newRevision.setAttachment("photo.jpg", "image/jpeg", stream);
 newRevision.save();
 }
 }
  • 67. ©2015  Couchbase  Inc. ‹#›
  • 68. ©2015  Couchbase  Inc. ‹#›
  • 69. ©2015  Couchbase  Inc. ‹#› http://bit.ly/1KKiA8g
  • 70. ©2015  Couchbase  Inc. ‹#› http://bit.ly/1FrUJn0
  • 71. iOS  branch:  worhsop/start   Android  branch:  workshop/initial_state

No comments:

Post a Comment