SlideShare une entreprise Scribd logo
1  sur  41
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6Introduction to Ecmascript - ES6
Introduction to Ecmascript - ES6Nilesh Jayanandana
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Sven Efftinge
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyRaimonds Simanovskis
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6Solution4Future
 
Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Ramamohan Chokkam
 
ECMAScript 6: A Better JavaScript for the Ambient Computing Era
ECMAScript 6: A Better JavaScript for the Ambient Computing EraECMAScript 6: A Better JavaScript for the Ambient Computing Era
ECMAScript 6: A Better JavaScript for the Ambient Computing EraAllen Wirfs-Brock
 
ElasticSearch for .NET Developers
ElasticSearch for .NET DevelopersElasticSearch for .NET Developers
ElasticSearch for .NET DevelopersBen van Mol
 
GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao IntroductionBooch Lin
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQLPeter Eisentraut
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.boyney123
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Ben Lesh
 

Tendances (20)

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

Similaire à Painless Persistence with Realm

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Jiayun Zhou
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryAlexandre Morgaut
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonAlex Payne
 
RMI Java Programming Lab Manual 2019
RMI Java Programming Lab Manual 2019RMI Java Programming Lab Manual 2019
RMI Java Programming Lab Manual 2019Gebreigziabher Ab
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chinjaxconf
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyYahoo
 
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...apidays
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 

Similaire à Painless Persistence with Realm (20)

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love Story
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 
RMI Java Programming Lab Manual 2019
RMI Java Programming Lab Manual 2019RMI Java Programming Lab Manual 2019
RMI Java Programming Lab Manual 2019
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
Java rmi
Java rmiJava rmi
Java rmi
 
3 database-jdbc(1)
3 database-jdbc(1)3 database-jdbc(1)
3 database-jdbc(1)
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - Italy
 
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
apidays LIVE Australia 2020 - Building distributed systems on the shoulders o...
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 

Dernier

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 

Dernier (20)

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 

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/