Bringing coffee tasting to rural areas with Ember & Cordova

Francesco Novy

@_fnovy

www.fnovy.com

hello@fnovy.com

mydea

Innsbruck

Requirements

  • iOS & Android
  • Fully offline capable
  • Maintainable
  • Easy to use

Why not PWA?

  • Wasn't even possible (iOS 8)
  • Workflow not clear to users
  • Doesn't feel as secure

Cropster Cup

Mobile app development

is hard

  1. Data storage is hard
  2. Transactionality is hard
  3. Operating offline is hard
  4. Fluid performance is hard
  5. Testing on real devices is hard
  6. Native development is hard
  7. App stores are hard
  8. Native deployment is hard

Data storage is hard

1/8

Local Storage?

IndexedDB!

ember-indexeddb

 version1: {
    stores: {
      'descriptor': '&id,json,*groupCode,*name',
      'group': '&id,json',
      'analysis-result': '&id,json,*session,*cuppingDate' 
    }
  }
ember install ember-indexeddb
// Syncing data from server

async function loadData() {
    let { ajax, indexedDb } = this;
    let data = await ajax.request('/descriptor');
    indexedDb.add('descriptor', data);
}
// Interacting with IndexedDB

let { store } = this;
store.findAll('descriptor');
store.query('descriptor', { name: 'Apple' });
store.findRecord('descriptor', '1');

let descriptor = store.createRecord('descriptor', { name: 'Apple' });
descriptor.save();
descriptor.destroyRecord();

Transactionality is hard

2/8

  • Special API endpoint
  • JSON:API 1.1 will hopefully include Operations

Operating offline is hard

3/8

create session

edit session

pull

push

timeline

???

X

Fluid performance is hard

4/8

{{#each analysisResults as |analysisResult i|}}
   {{#sample-delayed
       analysisResult=analysisResult
       delay=i
   }}
       {{sample-form
           analysisResult=analysisResult
       }}
   {{/sample-delayed}}
{{/each}}
// app/components/sample-delayed/component.js

didReceiveAttrs() {
   this.loadSample.perform();
},
loadSample: task(function* () {
   let delay = this.delay + 1;
   let delayMs = delay * 100;

   yield timeout(delayMs);
}).drop()
{{! app/components/sample-delayed/template.hbs }}

{{#if loadSample.isRunning}}
   {{loading-spinner}}
{{else}}
   {{yield}}
{{/if}}

Testing on real devices is hard

5/8

  • iPad (iOS 10)
  • iPad (iOS 11)
  • iPad (iOS 12)
  • iPhone (iOS 12)
  • Moto E
  • Nexus 6P
  • Samsung Galaxy Tab
  • Kindle Fire 7
  • Huawei Media Tab

Native development is hard

6/8

yarn global add corber
corber init
# Run your JavaScript builder and create a mobile application
corber build

# Boot an emulator with live reload for development
# Cordova plugins are supported /w live reload
corber start

# Set up hot reload for on-device usage
corber serve

# Build icon & splash screens
corber make-splashes
corber make-icons

App stores are hard

7/8

Deployment is hard

8/8

actually...

lane :deploy do
  match(
    type: "appstore",
    readonly: true
  )
  cordova(
    platform: 'ios',
    release: true,
    provisioning_profile: 'match AppStore com.cropster.cuppingapp'
  )
  appstore(
    ipa: ENV['CORDOVA_IOS_RELEASE_BUILD_PATH']
  )
end
bundler exec fastlane ios deploy
  • CI tool
  • Linux & Mac OS machines
  • CircleCI + fastlane = 

Thank you for your attention!

@_fnovy

www.fnovy.com

hello@fnovy.com

mydea

Made with Slides.com