Cloud Sync for App Developers
Leah Culver, Dropbox
Apps World Feb 2014
Slide 2
Slide 2 text
• Sync across devices
• Backup data
• User identification
• Offline access and sync
Mobile app challenges
Slide 3
Slide 3 text
Write your own backend API
Solution
Slide 4
Slide 4 text
Mobile backend service
(Parse, iCloud, etc.)
Solution
Slide 5
Slide 5 text
Dropbox for your mobile apps
• Cross-platform (Android, iOS, HTTP)
• Users’ own Dropbox account
• Caching, sync, and conflict resolution
Slide 6
Slide 6 text
Dropbox APIs
Files
• Drop-ins: lightweight chooser / saver
• Core API: HTTP REST-ish API
• Sync API: file system-like interface
!
Data
• Datastore API: structured data
Slide 7
Slide 7 text
Chooser
User opens a file from their Dropbox
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
Trigger the Chooser
- (void)didPressChoose {
DBChooser *chooser = [DBChooser defaultChooser];
!
[chooser openChooserForLinkType:DBChooserLinkTypePreview
fromViewController:self
completion:^(NSArray *results)
{
if ([results count]) {
// Process results
} else {
// User cancelled
}
}];
}
Slide 10
Slide 10 text
Chooser
Returns:
• link - preview or direct
• thumbnails - for photo and video
• file name, icon, and size
Slide 11
Slide 11 text
Core API
• REST-ish, OAuth 2.0, JSON
• Android, iOS, OS X, Python, Ruby,
Java, PHP
• Community-supported libraries for
C#, JavaScript, Perl, etc.
HTTP API for files
Slide 12
Slide 12 text
Permissions
Slide 13
Slide 13 text
Permissions
• App folder
Permission to a specific folder
!
• File types
Permission to a class of files (e.g. images)
!
• Full Dropbox
Permission to everything
Slide 14
Slide 14 text
Sync API
• Files for your app in your user’s Dropbox
• Store and sync photos, videos, files, etc.
• SDKs handle offline caching and syncing
• Notifications of changes
Slide 15
Slide 15 text
List files on Android
Slide 16
Slide 16 text
Listen for changes
Slide 17
Slide 17 text
Datastore API
Key-value store for structured data
(not files )
Slide 18
Slide 18 text
account→datastore→table→record→field→value
Datastore API
Slide 19
Slide 19 text
Add record on iOS
DBTable *table = [self.store getTable:@"tasks"];
NSDictionary *newTask = @{@"name": @"Buy milk"};
[table insert:newTask];
[self.store sync:nil];
Listen for changes
[self.store addObserver:self block:^() {
if (weakSelf.store.status & DBDatastoreIncoming) {
NSDictionary *changes = [weakSelf.store sync:nil];
// Do something…
});
}];
Slide 22
Slide 22 text
• Local changes cached when offline
• Syncs deltas with server when online
• Automatically merge changes
Offline / online syncing
Slide 23
Slide 23 text
• Changes as objects (deltas)
• Client sends delta(s) with “parent
revision”
• Server rejects a delta if parent revision
doesn’t match
• Server sends list of deltas to catch up
• Client resolves conflict, sends new delta
Conflict resolution
Slide 24
Slide 24 text
• Changes to different records commute
• Deletions win
• Changes to the same field are merged
Conflict resolution
Slide 25
Slide 25 text
Customizable per-field:
• Remote (default) - server wins
• Local - client wins
• Max - greater value wins
• Min - lesser value wins
• Sum - adds differences together
Conflict resolution