SlideShare a Scribd company logo
Painless Persistence
with Realm
Foo Café Stockholm
Christian Melchior
@chrmelchior
cm@realm.io
cm@realm.io
cm@realm.io
Design for offline
• A better USER EXPERIENCE!
• You always have something to show to the user.
• Reduce network requests and data transferred.
• Saves battery.
• It is 2016.
cm@realm.io
cm@realm.io
Offline architecture?
MVVM
MVC
Flux
Clean
Architecture
?
?
? ?
?
?
?
?
?
?
?
?
??
??
MVP
VIPER
cm@realm.io
They all have a model
MVVM
MVC
Flux
Clean
Architecture
MVP
VIPER
ModelView
getData()
data
cm@realm.io
You’re doing it wrong
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Setup initial views

setContentView(R.layout.activity_main);

// Load data from the REST API and show it

myApi = retrofit.create(NYTimesService.class);

myApi.topStories("home", "my-key")

.subscribe(new Action1<List<NYTimesStory>>() {

@Override

public void call(List<NYTimesStory> response) {

showList(response);

}

}, new Action1<Throwable>() {

@Override

public void call(Throwable throwable) {

showError(throwable);

}

});

}

cm@realm.io
You’re doing it right
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Setup initial views

setContentView(R.layout.activity_main);

// Load data from the Model and show it

model = ((MyApplication) getApplicationContext()).getModel();
model.getTopStories()

.subscribe(new Action1<List<NYTimesStory>>() {

@Override

public void call(List<NYTimesStory> response) {

showList(response);

}

}, new Action1<Throwable>() {

@Override

public void call(Throwable throwable) {

showError(throwable);

}

});

}

cm@realm.io
Encapsulate data
ModelView
Cache
Database
Network
cm@realm.io
Repository pattern
ModelView
Cache
Database
Network
Repository
Business rules
Creating/fetching data
Repository pattern
• Repository only have CRUD methods.
• Create()
• Read()
• Update()
• Delete()
• Model and repository can be tested
separately.
• http://hannesdorfmann.com/android/
evolution-of-the-repository-pattern
cm@realm.io
cm@realm.io
Designing for offline
Repository… DatastoregetData()
Observable<Data>()
Network
Update?
Fetch
Repository… DatastoregetData()
Observable<Data>()
Network
Update?
Save
Designing for offline
• Encapsulate data access.
• The datastore is “Single Source of Truth”.
• Everything is asynchronous.
• Observer pattern
• RxJava
• EventBus
• Testing becomes easier.
cm@realm.io
Realm
cm@realm.io
A Replacement for SQLite and ORM’s
Why choose Realm?
cm@realm.io
• A database designed for mobile from the ground up
• NoSQL (but not schemaless)
• Objects all the way down
• Reactive
• Cross-platform
Why choose Realm?
cm@realm.io
What does Realm look like?
cm@realm.io
public class Person extends RealmObject {

@PrimaryKey

private long id;

private String name;

private int age;



// References

private Dog dog;

private RealmList<Cat> cats;
// Methods

// …

}

Saving data
cm@realm.io
realm.executeTransaction(new Realm.Transaction() {

@Override

public void execute(Realm realm) {

// Create Object directly

Person person = realm.createObject(Person.class);

person.setId(1);

person.setName("Young Person");

person.setAge(14);



// Or insert a normal Java object

Person p = new Person(1, "Young Person", 14);

realm.insertOrUpdate(p);

}

});

Queries
cm@realm.io
// Synchronous queries
RealmResults<Person> results = realm.where(Person.class)

.between("age", 7, 9)

.beginsWith("name", "Person")

.isNull("dog")

.findAll();

// Asynchronous queries
RealmResults<Person> results = realm.where(Person.class)

.equalTo("dogs.name", "Fido")

.findAllAsync();



results.addChangeListener(new RealmChangeListener<RealmResults<Person>>() {

@Override

public void onChange(RealmResults<Person> results) {

showUI(results);

}

});

Realm SQLite
cm@realm.io
A
B C
D E F
G
cm@realm.io
References are first class
SELECT person.name, dog.name


FROM person

INNER JOIN dog ON person.dog_id = dog.id

WHERE person.name = ‘Frank’
RealmResults<Person> results;
results = realm.where(Person.class)

.equalTo("name", "Frank")

.findAll();


String name = results.first()
.getDog().getName();
cm@realm.io
References are first class
• No JOIN’s.
• No object-relational impedance mismatch.
• ID’s not required for references.
• Navigating the object graph is as fast as
following normal references.
Zero copy / Lazy loading
cm@realm.io
	Person	{	
• name	=	Tommy	
• age	=	8	
• dog	=	{	
• name	=	Lassie		
			}	
	}
	Person	{	
• name	=	Tommy	
• age	=	8	
• dog	=	{	
• name	=	Lassie		
			}	
	}
	Person	{	
• name	=	Tommy	
• age	=	8	
• dog	=	{	
• name	=	Lassie		
			}	
	}
	PersonProxy	{	
• name	
• age	
• dog		
	}
	PersonProxy	{	
• name	
• age	
• dog		
	}
	Person	{	
• name	=	Tommy	
• age	=	8	
• dog	=	{	
• name	=	Lassie		
			}	
	}
Zero copy / Lazy loading
cm@realm.io
• Realm is always Single Source of Truth
• RealmResults ~= Typesafe Cursor
• Memory efficient
• No need for LIMIT and Load More buttons
Caveat
• Consider caching values if used in a loop.
cm@realm.io
Threading model
Model
• MVCC
• Each thread has a consistent
view.
• Thread confined objects.
API’s
• Change listeners
Model
• Your on your own
API’s
• Loaders
• ContentObservers
• ContentProviders
• RxJava (3rd party)
• SQLBrite (3rd party)
Implementing offline-first
cm@realm.io
In 3 easy steps
3xR: Realm, Retrofit and RxJava
cm@realm.io
buildscript {

dependencies {

classpath 'io.realm:realm-gradle-plugin:2.0.2'

}

}



dependencies {
compile 'com.google.code.gson:gson:2.7'

compile 'io.reactivex:rxjava:1.2.1'

compile 'com.squareup.retrofit2:retrofit:2.1.0'

compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
}
apply plugin: 'realm-android'

3xR-1: Setup Retrofit
cm@realm.io
public interface NYTimesService {

@GET("svc/topstories/v1/{section}.json")

Observable<List<NYTimesStory>> topStories(

@Path("section") String section,

@Query(value = "api-key", encoded = true) String apiKey);

}
Retrofit retrofit = new Retrofit.Builder()

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.addConverterFactory(GsonConverterFactory.create())

.baseUrl("http://api.nytimes.com/")

.build();



NYTimesService api = retrofit.create(NYTimesService.class);

3xR-2: Save data
cm@realm.io
// Load data from the network and insert into Realm

api.topStories("home", apiKey).asObservable().subscribe(new
Action1<List<NYTimesStory>>() {

@Override

public void call(final List<NYTimesStory> stories) {

Realm realm = Realm.getDefaultInstance();

realm.executeTransaction(r -> {

r.insertOrUpdate(stories);

});

realm.close();

}

}, new Action1<Throwable>() {

@Override

public void call(Throwable throwable) {

retryOrHandleError(throwable);

}

});

3xR-3: Listen for changes
cm@realm.io
// Realm Observables never complete, updating your UI if anything changes
Realm realm = Realm.getDefaultInstance();

realm.where(NYTimesStory.class)

.findAllSortedAsync("published_date", Sort.DESCENDING)

.asObservable()

.subscribe(new Action1<RealmResults<NYTimesStory>>() {

@Override

public void call(RealmResults<NYTimesStory> stories) {

updateUI(stories);

}

});

3xR: Benefits
cm@realm.io
• Offline first with very few lines of code.
• Decouple Network and UI .
• Reactive UI: No matter where the update come
from, your UI will reflect it.
Realm Mobile Platform
cm@realm.io
Automatic synchronisation between devices
REST API’s Today
cm@realm.io
Synchronising changes
• Server always wins
• Easy
• Client not allowed to write or risk loosing changes.
• Client can win
• Hard
• Complexity explosion
• Changes needs to be tracked and merged.
cm@realm.io
What if we removed all that?
cm@realm.io
Native Realm Object
Realm Object Server
Only Realm
Native object
JSON
Backend object
SQL
Backend object
JSON
Native object
SQLite/CoreData SQLite/CoreData
e.g. Firebase, Parse, etc.
Synchronising a local Realm
cm@realm.io
apply plugin: 'realm-android'



realm {

syncEnabled = true

}

cm@realm.io
SyncCredentials creds = SyncCredentials.usernamePassword(username, password, createUser);

SyncUser.loginAsync(creds, "https://my.server/auth", new SyncUser.Callback() {

@Override

public void onSuccess(SyncUser user) {

openRealm(user);

}



@Override

public void onError(ObjectServerError error) {

handleError(error);

}

});

Synchronising a local Realm
cm@realm.io
// Opening a local Realm

RealmConfiguration config = new RealmConfiguration.Builder().build();

Realm realm = Realm.getInstance(config);



// Opening a synchronized Realm
SyncUser user = login();

String url = "realm://my.server/~/default";

SyncConfiguration config = new SyncConfiguration.Builder(user, url).build();

Realm realm = Realm.getInstance(config);

Synchronising a local Realm
Features
cm@realm.io
• Automatic conflict resolution using Operational Transform.
• Offline first.
• Same reactive pattern on the Client and the Server.
• Node.js API on the server side for integration with other
DB’s or API’s.
Take aways
cm@realm.io
• Design for offline first - no excuse in 2016
• Repository pattern for decoupling and testability.
• Try Realm - https://realm.io/
cm@realm.io
Questions?
Christian Melchior
cm@realm.io
www.realm.io
@chrmelchior

More Related Content

PDF
PPTX
Realm - Phoenix Mobile Festival
PDF
Painless Persistence in a Disconnected World
PDF
Realm: Building a mobile database
PDF
Advanced realm in swift
ODP
Realm Mobile Database - An Introduction
PDF
Realm of the Mobile Database: an introduction to Realm
PDF
Useful and Practical Functionalities in Realm
Realm - Phoenix Mobile Festival
Painless Persistence in a Disconnected World
Realm: Building a mobile database
Advanced realm in swift
Realm Mobile Database - An Introduction
Realm of the Mobile Database: an introduction to Realm
Useful and Practical Functionalities in Realm

What's hot (20)

PDF
Http4s, Doobie and Circe: The Functional Web Stack
PPTX
Introduction to Ecmascript - ES6
PDF
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
PDF
ES6: The Awesome Parts
PDF
Rails on Oracle 2011
PPTX
Getting started with Elasticsearch and .NET
PDF
Node Boot Camp
KEY
Getting the most out of Java [Nordic Coding-2010]
PDF
Why Every Tester Should Learn Ruby
PDF
JavaScript - new features in ECMAScript 6
PDF
Automatically generating-json-from-java-objects-java-objects268
PDF
greenDAO
PPT
ECMAScript 6: A Better JavaScript for the Ambient Computing Era
PPTX
ElasticSearch for .NET Developers
PDF
Requery overview
PPTX
GreenDao Introduction
PDF
Programming with Python and PostgreSQL
PDF
Introduction into ES6 JavaScript.
PPTX
Async Redux Actions With RxJS - React Rally 2016
PDF
Green dao
Http4s, Doobie and Circe: The Functional Web Stack
Introduction to Ecmascript - ES6
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
ES6: The Awesome Parts
Rails on Oracle 2011
Getting started with Elasticsearch and .NET
Node Boot Camp
Getting the most out of Java [Nordic Coding-2010]
Why Every Tester Should Learn Ruby
JavaScript - new features in ECMAScript 6
Automatically generating-json-from-java-objects-java-objects268
greenDAO
ECMAScript 6: A Better JavaScript for the Ambient Computing Era
ElasticSearch for .NET Developers
Requery overview
GreenDao Introduction
Programming with Python and PostgreSQL
Introduction into ES6 JavaScript.
Async Redux Actions With RxJS - React Rally 2016
Green dao
Ad

Similar to Painless Persistence with Realm (20)

PDF
#MBLTdev: Уроки, которые мы выучили, создавая Realm
PDF
MongoDB .local Bengaluru 2019: Realm: The Secret Sauce for Better Mobile Apps
PDF
Introduction to Realm Mobile Platform
PPTX
Realm mobile database
PDF
React-Native Lecture 11: In App Storage
PPTX
Present realm
PPTX
RealmDB for Android
PDF
No sql databases blrdroid devfest 2016
PDF
Realm Java 2.2.0: Build better apps, faster apps
PDF
Realm Java 2.2.0: Build better apps, faster apps
PDF
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
PPTX
Realm Java for Android
PDF
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
PDF
MongoDB World 2019: Realm: The Secret Sauce for Better Mobile Apps
PPTX
Realm database
PDF
MongoDB .local Houston 2019: REST-less Mobile Apps: Why Offline-first and Syn...
PDF
Realm.io par Clement Sauvage
PPTX
iOS Dev Happy Hour Realm - Feb 2021
PDF
Realm Presentation
PDF
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
#MBLTdev: Уроки, которые мы выучили, создавая Realm
MongoDB .local Bengaluru 2019: Realm: The Secret Sauce for Better Mobile Apps
Introduction to Realm Mobile Platform
Realm mobile database
React-Native Lecture 11: In App Storage
Present realm
RealmDB for Android
No sql databases blrdroid devfest 2016
Realm Java 2.2.0: Build better apps, faster apps
Realm Java 2.2.0: Build better apps, faster apps
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
Realm Java for Android
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB World 2019: Realm: The Secret Sauce for Better Mobile Apps
Realm database
MongoDB .local Houston 2019: REST-less Mobile Apps: Why Offline-first and Syn...
Realm.io par Clement Sauvage
iOS Dev Happy Hour Realm - Feb 2021
Realm Presentation
MongoDB .local Chicago 2019: REST-less Mobile Apps: Why Offline-first & Sync ...
Ad

Recently uploaded (20)

PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
project resource management chapter-09.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Hindi spoken digit analysis for native and non-native speakers
PPTX
Tartificialntelligence_presentation.pptx
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
Approach and Philosophy of On baking technology
PDF
1 - Historical Antecedents, Social Consideration.pdf
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PDF
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PPTX
A Presentation on Touch Screen Technology
PDF
Encapsulation theory and applications.pdf
Heart disease approach using modified random forest and particle swarm optimi...
Web App vs Mobile App What Should You Build First.pdf
project resource management chapter-09.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
NewMind AI Weekly Chronicles - August'25-Week II
Hindi spoken digit analysis for native and non-native speakers
Tartificialntelligence_presentation.pptx
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Unlocking AI with Model Context Protocol (MCP)
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
Approach and Philosophy of On baking technology
1 - Historical Antecedents, Social Consideration.pdf
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
A comparative analysis of optical character recognition models for extracting...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
A Presentation on Touch Screen Technology
Encapsulation theory and applications.pdf

Painless Persistence with Realm

  • 1. Painless Persistence with Realm Foo Café Stockholm Christian Melchior @chrmelchior cm@realm.io
  • 4. Design for offline • A better USER EXPERIENCE! • You always have something to show to the user. • Reduce network requests and data transferred. • Saves battery. • It is 2016. cm@realm.io
  • 6. cm@realm.io They all have a model MVVM MVC Flux Clean Architecture MVP VIPER ModelView getData() data
  • 7. cm@realm.io You’re doing it wrong @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 // Setup initial views
 setContentView(R.layout.activity_main);
 // Load data from the REST API and show it
 myApi = retrofit.create(NYTimesService.class);
 myApi.topStories("home", "my-key")
 .subscribe(new Action1<List<NYTimesStory>>() {
 @Override
 public void call(List<NYTimesStory> response) {
 showList(response);
 }
 }, new Action1<Throwable>() {
 @Override
 public void call(Throwable throwable) {
 showError(throwable);
 }
 });
 }

  • 8. cm@realm.io You’re doing it right @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 // Setup initial views
 setContentView(R.layout.activity_main);
 // Load data from the Model and show it
 model = ((MyApplication) getApplicationContext()).getModel(); model.getTopStories()
 .subscribe(new Action1<List<NYTimesStory>>() {
 @Override
 public void call(List<NYTimesStory> response) {
 showList(response);
 }
 }, new Action1<Throwable>() {
 @Override
 public void call(Throwable throwable) {
 showError(throwable);
 }
 });
 }

  • 11. Repository pattern • Repository only have CRUD methods. • Create() • Read() • Update() • Delete() • Model and repository can be tested separately. • http://hannesdorfmann.com/android/ evolution-of-the-repository-pattern cm@realm.io
  • 12. cm@realm.io Designing for offline Repository… DatastoregetData() Observable<Data>() Network Update? Fetch Repository… DatastoregetData() Observable<Data>() Network Update? Save
  • 13. Designing for offline • Encapsulate data access. • The datastore is “Single Source of Truth”. • Everything is asynchronous. • Observer pattern • RxJava • EventBus • Testing becomes easier. cm@realm.io
  • 15. Why choose Realm? cm@realm.io • A database designed for mobile from the ground up • NoSQL (but not schemaless) • Objects all the way down • Reactive • Cross-platform
  • 17. What does Realm look like? cm@realm.io public class Person extends RealmObject {
 @PrimaryKey
 private long id;
 private String name;
 private int age;
 
 // References
 private Dog dog;
 private RealmList<Cat> cats; // Methods
 // …
 }

  • 18. Saving data cm@realm.io realm.executeTransaction(new Realm.Transaction() {
 @Override
 public void execute(Realm realm) {
 // Create Object directly
 Person person = realm.createObject(Person.class);
 person.setId(1);
 person.setName("Young Person");
 person.setAge(14);
 
 // Or insert a normal Java object
 Person p = new Person(1, "Young Person", 14);
 realm.insertOrUpdate(p);
 }
 });

  • 19. Queries cm@realm.io // Synchronous queries RealmResults<Person> results = realm.where(Person.class)
 .between("age", 7, 9)
 .beginsWith("name", "Person")
 .isNull("dog")
 .findAll();
 // Asynchronous queries RealmResults<Person> results = realm.where(Person.class)
 .equalTo("dogs.name", "Fido")
 .findAllAsync();
 
 results.addChangeListener(new RealmChangeListener<RealmResults<Person>>() {
 @Override
 public void onChange(RealmResults<Person> results) {
 showUI(results);
 }
 });

  • 21. cm@realm.io References are first class SELECT person.name, dog.name 
 FROM person
 INNER JOIN dog ON person.dog_id = dog.id
 WHERE person.name = ‘Frank’ RealmResults<Person> results; results = realm.where(Person.class)
 .equalTo("name", "Frank")
 .findAll(); 
 String name = results.first() .getDog().getName();
  • 22. cm@realm.io References are first class • No JOIN’s. • No object-relational impedance mismatch. • ID’s not required for references. • Navigating the object graph is as fast as following normal references.
  • 23. Zero copy / Lazy loading cm@realm.io Person { • name = Tommy • age = 8 • dog = { • name = Lassie } } Person { • name = Tommy • age = 8 • dog = { • name = Lassie } } Person { • name = Tommy • age = 8 • dog = { • name = Lassie } } PersonProxy { • name • age • dog } PersonProxy { • name • age • dog } Person { • name = Tommy • age = 8 • dog = { • name = Lassie } }
  • 24. Zero copy / Lazy loading cm@realm.io • Realm is always Single Source of Truth • RealmResults ~= Typesafe Cursor • Memory efficient • No need for LIMIT and Load More buttons Caveat • Consider caching values if used in a loop.
  • 25. cm@realm.io Threading model Model • MVCC • Each thread has a consistent view. • Thread confined objects. API’s • Change listeners Model • Your on your own API’s • Loaders • ContentObservers • ContentProviders • RxJava (3rd party) • SQLBrite (3rd party)
  • 27. 3xR: Realm, Retrofit and RxJava cm@realm.io buildscript {
 dependencies {
 classpath 'io.realm:realm-gradle-plugin:2.0.2'
 }
 }
 
 dependencies { compile 'com.google.code.gson:gson:2.7'
 compile 'io.reactivex:rxjava:1.2.1'
 compile 'com.squareup.retrofit2:retrofit:2.1.0'
 compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' } apply plugin: 'realm-android'

  • 28. 3xR-1: Setup Retrofit cm@realm.io public interface NYTimesService {
 @GET("svc/topstories/v1/{section}.json")
 Observable<List<NYTimesStory>> topStories(
 @Path("section") String section,
 @Query(value = "api-key", encoded = true) String apiKey);
 } Retrofit retrofit = new Retrofit.Builder()
 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
 .addConverterFactory(GsonConverterFactory.create())
 .baseUrl("http://api.nytimes.com/")
 .build();
 
 NYTimesService api = retrofit.create(NYTimesService.class);

  • 29. 3xR-2: Save data cm@realm.io // Load data from the network and insert into Realm
 api.topStories("home", apiKey).asObservable().subscribe(new Action1<List<NYTimesStory>>() {
 @Override
 public void call(final List<NYTimesStory> stories) {
 Realm realm = Realm.getDefaultInstance();
 realm.executeTransaction(r -> {
 r.insertOrUpdate(stories);
 });
 realm.close();
 }
 }, new Action1<Throwable>() {
 @Override
 public void call(Throwable throwable) {
 retryOrHandleError(throwable);
 }
 });

  • 30. 3xR-3: Listen for changes cm@realm.io // Realm Observables never complete, updating your UI if anything changes Realm realm = Realm.getDefaultInstance();
 realm.where(NYTimesStory.class)
 .findAllSortedAsync("published_date", Sort.DESCENDING)
 .asObservable()
 .subscribe(new Action1<RealmResults<NYTimesStory>>() {
 @Override
 public void call(RealmResults<NYTimesStory> stories) {
 updateUI(stories);
 }
 });

  • 31. 3xR: Benefits cm@realm.io • Offline first with very few lines of code. • Decouple Network and UI . • Reactive UI: No matter where the update come from, your UI will reflect it.
  • 32. Realm Mobile Platform cm@realm.io Automatic synchronisation between devices
  • 34. Synchronising changes • Server always wins • Easy • Client not allowed to write or risk loosing changes. • Client can win • Hard • Complexity explosion • Changes needs to be tracked and merged. cm@realm.io
  • 35. What if we removed all that? cm@realm.io Native Realm Object Realm Object Server Only Realm Native object JSON Backend object SQL Backend object JSON Native object SQLite/CoreData SQLite/CoreData e.g. Firebase, Parse, etc.
  • 36. Synchronising a local Realm cm@realm.io apply plugin: 'realm-android'
 
 realm {
 syncEnabled = true
 }

  • 37. cm@realm.io SyncCredentials creds = SyncCredentials.usernamePassword(username, password, createUser);
 SyncUser.loginAsync(creds, "https://my.server/auth", new SyncUser.Callback() {
 @Override
 public void onSuccess(SyncUser user) {
 openRealm(user);
 }
 
 @Override
 public void onError(ObjectServerError error) {
 handleError(error);
 }
 });
 Synchronising a local Realm
  • 38. cm@realm.io // Opening a local Realm
 RealmConfiguration config = new RealmConfiguration.Builder().build();
 Realm realm = Realm.getInstance(config);
 
 // Opening a synchronized Realm SyncUser user = login();
 String url = "realm://my.server/~/default";
 SyncConfiguration config = new SyncConfiguration.Builder(user, url).build();
 Realm realm = Realm.getInstance(config);
 Synchronising a local Realm
  • 39. Features cm@realm.io • Automatic conflict resolution using Operational Transform. • Offline first. • Same reactive pattern on the Client and the Server. • Node.js API on the server side for integration with other DB’s or API’s.
  • 40. Take aways cm@realm.io • Design for offline first - no excuse in 2016 • Repository pattern for decoupling and testability. • Try Realm - https://realm.io/