Top Banner
Build offline first with Couchbase & Feather Matias Piipari (@mz2) CEO & Co-founder, Manuscriptsapp.com CTO, Papersapp.com
45

Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Aug 11, 2015

Download

Technology

Couchbase
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Build offline first withCouchbase & Feather

Matias Piipari (@mz2)CEO & Co-founder, Manuscriptsapp.comCTO, Papersapp.com

Page 2: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 3: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Manuscripts.appA Couchbase Lite powered writing tool

for complex documents.

Page 4: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Word processor & Couchbase?

Page 5: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 6: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 7: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 8: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

http://your-data

Page 9: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 10: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Web frontend

Manuscript contents Author name / affiliation data Citation data

Feather (Couchbase Lite model)

Web model (e.g. PouchDB)

Mac app UI

Page 11: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Sync and share your manuscripts

Page 12: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

You own and control your dataEnd-user is our customer, not part of the product.

Page 13: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Individual Individual + co-author / supervisor

Group of collaborators

Page 14: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

50+ model entity types

Page 15: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

~30K documents + attachments.Compresses to 60+ MB of pre-bundled content

Page 16: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Crowdsourced data

Page 17: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Cross-platform data access

Page 18: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Why Couchbase Lite?

1. Serve the data and its change feed over HTTP.

2. Focus on delivering a great offline experience.

3. Object-document mapping and attachments.

4. Sync is about conflict resolution and model robustness.

5. Sync is available peer-to-peer, between local databases.

6. Gives us + the end user control over data.

7. Cross-platform (Core Data).

8. Low memory footprint, fast start-up doesn't hurt on desktop.

9. Runtime performance drawbacks less of a concern on desktop.

10. Source code is readable.

Page 19: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

❤Couchbase is

a great open source project. ❤

Page 20: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 21: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

"Why does everything have to work so differently

in Couchbase?"— Anonymous Cocoa developer.

Page 22: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

What is different?

• Data modeling.

• Database querying.

• Consistency.

• Data validation.

• Performance bottlenecks.

• [...]

Page 23: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 24: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Speed up common tasks.Impose structure and conventions.

Page 25: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Feather: utilities and conventions.• Partition data to multiple databases (speed + storage size).

• Manage repositories, or 'collections', of model objects.

• Mix-ins for unrelated model entities to share behaviour.

• Pre-compute data shipped in the app.

• Support nested object collections / trees in a document.

• Help with making the data model scriptable.

Page 26: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Contents database Authors database Bibliography database

Sections repository

User visible database package A

(~/Documents/thesis.manuscript)

Paragraphs repository Styles repository

Model object controllers

Section model Paragraph modelParagraph style

Model object

Margin

Citation repository

Citation

Cite “Piipari et al (2014)”

Cite “Hubbard et al (2011)”Embedded objects

Shared database package(~/Library/Application Support/Manuscripts)

Styles

User visible database package A

(~/Documents/conf-abstract.manuscript)Contents database Authors database Bibliography

database Styles

Styles databaseTemplates databaseFunders database

Page 27: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

✨ Model objects and model object controllers ✨

• Model is dumb.

• Object controller for CRUD.

• XsController is implictly repository for models of type X (can be overriden).

• Observer callbacks for didAddX, didUpdateX, didDeleteX given.

• Properties which are prefixed cached are… cached.

• Properties which are prefixed embedded contain… embedded objects.

• Principle: if you're going to fail, detect it during startup.

Page 28: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Embedded objects• Nested in the containing object's JSON representation.

• Nested collections supported (arrays, sets, dictionaries).

• A nested object itself nests objects or collections of objects.

• Propagates changes to containing top-level model object.

Page 29: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Bibliography database

Database package

Citation repository

Citation

Cite “Piipari et al (2014)”

Cite “Hubbard et al (2011)”

Page 30: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Embedded object collections// Exhibit A: citation

@interface MPCitation : MPManagedObject

/** Array of MPCitationItem objects. */@property (readwrite) NSArray *embeddedCitationItems;

@end

@interface MPCitationItem : MPEmbeddedObject

@property (readonly, strong) MPBibliographyEntry *bibliographyEntry;

@end

Page 31: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Querying data/** Query the view with the given keys, * and return managed object representations. * * @param view name of the view queried. * @param an array of keys, or nil * @return * */- (NSArray *)objectsMatchingQueriedView:(NSString *)view keys:(NSArray *)keys;

- (NSArray *)contributorsInRole:(NSString *)role { return [self objectsMatchingQueriedView:@"contributorsByRole" keys:@[role]];}

Page 32: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Respond to object graph changes• Model objects and repositories observe for add / update / delete.

• A callback naming convention for notification handlers.

• Automated cache busting.- (NSArray *)borderStyles { if (!_cachedBorderStyles) { _cachedBorderStyles = [self stylesOfClass:MPBorderStyle.class]; }

return _cachedBorderStyles;}

Page 33: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Cascading object look-ups1. Get data from a database package.

2. If you found it, get it.

3. If you didn't find it, fall back to shared database package.

• Use-case: cascading style system.

• A more complex case: effective properties (follow a tree).

• Visitors: deep save a subgraph of objects.

Page 34: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Built-in support for tracking contributorship"Get authors contributing to paragraph X?""Get content contributed to by Y""Get me the author who most recently contributed to figure Z?"

Page 35: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Pasteboard support• NSPasteboard writing and reading support.

• An 'object reference': a fully qualified identifier for object.

• Uniquely identifies object also when multiple DBs with same document revision are open.

• Handy for supporting drag & drop.

Page 36: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

HTTP listener• Easy API for spinning up the HTTP listener.

• Try a port, back off, then try again a few more times before failing.

/** If callback is not implemented, listener is added. * If callback is implemented, YES return value causes a listener to be created, * NO leads to it being omitted. * * Listener is by default not started for XPC services, * command line tools and when the package controller * has not been set to synchronize peerlessly (`-synchronizesPeerlessly`). */ - (BOOL)packageControllerRequiresListener:(MPDatabasePackageController *)packageController;

Page 37: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

State initialisation & placeholder1. Bundle data by loading a JSON file

(MPManuscriptTemplatesController --> manuscript-templates.json)

2. Bundle data by pulling from a bundled CBL database

(MPManuscriptTemplatesController --> manuscript-templates.cblite).

3. Bundle data by copying a bundled CBL database in.

• Initial state (e.g. required documents at expected state).

• Placeholder content: e.g. on-boarding content.

- (id)ensureInitialStateInitialized { return [self ensurePrimaryManuscriptInitialized];}

Page 38: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Saving• 'session' property: track which party created a certain

revision.

• 'contributor': documents have an array of ordered contributor IDs.

• e.g. distinguish changes between different devices / writers.

Page 39: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Model mixins+ (void)implementProtocol:(Protocol *)protocol andProtocolsMatching:(MPAdoptedProtocolPatternBlock)patternBlock overloadMethods:(BOOL)overloadMethods;

+ (void)initialize { if (self == [MPDraft class]) [self implementProtocol:@protocol(MPDeliverable) overloadMethods:NO];}

Page 40: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

@protocol MPDeliverable <NSObject>

@optional // methods optional to avoid compiler errors with Objective-Mixin

@property (readwrite, strong) NSDate *deadline;@property (readwrite, strong) MPContributor *responsibleContributor;@property (readwrite) MPImportance importance;@property (readonly) NSString *humanReadableImportance;

@property (readwrite, strong) MPLabel *statusLabel;

@property (readwrite) MPProgressLevel progressLevel;@property (readonly) NSString *humanReadableProgressLevel;

@property (readonly, strong) NSArray *requirements;

@property (readonly) CGFloat progress;

- (void)addRequirement:(MPRequirement *)requirement;- (BOOL)removeRequirement:(MPRequirement *)requirement;

- (MPRequirementEvaluation)meetsRequirement:(MPRequirement *)req;

@end

Page 41: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Stapler: a utility for bundling data from JSON to a CBL 'database package'

Input:

• A series of JSON files describing documents to load.

• Optional: path to attachment metadata.

Output: a Feather database package.

Stapler --target ./csl/bundles \--objectType MPBundle \--source ./csl/csl-data.json \--attachments ./csl/csl-paths.json

Page 42: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

feather-grep: a Node.js commandline helper for grepping Feather data.

➜ Projects feather-grep -o MPManuscriptCategory -k name,desc,objectType '/Users/mz2/Library/Application Support/Manuscripts'

'MPManuscriptCategory:F9EC50FB-7E8D-4D47-BBEC-7A4E709B9306' : '1-1db4dade18b4d106d779cb640113c0bb'

{ name: 'Book',

desc: 'Books & Book chapters',

objectType: 'MPManuscriptCategory' }

'MPManuscriptCategory:714D3A21-C0F9-46A9-80D8-13796818098B' : '1-985e08c3be9829986719241f03eda379'

{ name: 'Dissertation',

desc: 'Master\'s & PhD theses, and other dissertations.',

objectType: 'MPManuscriptCategory' }

Page 43: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Model scriptability (JS / AppleScript)

• A scripting category for model and repository classes.

• A 1000+ line .sdef XML with mostly silent error handling --> nightmare.

• Hence wrote MPScriptingDefinitionManager: a runtime .sdef validator.

Page 44: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015
Page 45: Building Powerful Mac + iOS Apps with Couchbase Lite and Feather: Couchbase Connect 2015

Thank you!github.com/mpapp/Feather.git

[email protected] (@mz2)