Upgrade to Pro — share decks privately, control downloads, hide ads and more …

KotlinConf_2019_Server_Driven_UI.pdf

Laura Kelly
December 05, 2019
290

 KotlinConf_2019_Server_Driven_UI.pdf

Laura Kelly

December 05, 2019
Tweet

Transcript

  1. API Response (not SDUI) Name: “Sightglass Coffee”, Photos: {…} Website:

    “www.sightglasscoffee.com”, Location: { address: “123 main street”, city: “San Francisco”, state: “California”, country: “United States" },
  2. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  3. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  4. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  5. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  6. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  7. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  8. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } "dismiss" "logout" "asyncRequest" … Lona Component JSON
  9. { "id": "…", "type": "MyComponent", "content": { "title": "My Title",

    "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } } Lona Component JSON
  10. Lona Component JSON { "id": "…", "type": “MyComponent”, "content": {

    "title": "My Title", "subtitle": "…" }, "actions": { "onPress": { "case": "deepLink", "data": { "url": "https://…" } } } }
  11. • Versioning • Keeping clients in sync • Scaling •

    Documentation Challenges of server-driven UI
  12. ?

  13. ?! est.tabs.TabChooser.onCreate(TabChooser.java:15) 1-21 20:55:47.390: W/System.err(989): at ndroid.app.Activity.performCreate(Activity.java:4465) 1-21 20:55:47.410: W/System.err(989):

    at ndroid.app.Instrumentation.callActivityOnCreate(Instr mentation.java:1049) 1-21 20:55:47.410: W/System.err(989): at ndroid.app.ActivityThread.performLaunchActivity(Activ tyThread.java:1919) 1-21 20:55:47.420: W/System.err(989): at ndroid.app.ActivityThread.handleLaunchActivity(Activi yThread.java:1980) 1-21 20:55:47.420: W/System.err(989): at ndroid.app.ActivityThread.access$600(ActivityThread.j va:122)
  14. Me

  15. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) { description("Documentation about this property.") } }
  16. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) { description("Documentation about this property.") example("Title") example("A really long title to test this use case…") } }
  17. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) { description("Documentation about this property.") example("Title") example("A really long title to test this use case…") } optionalContent("subtitle", Type.String, nullable = true, default = null) … } }
  18. Lona Spec DSL val optionalContentSubtitle: LonaComponent.Builder.() -> Unit = {

    optionalContent("subtitle", Type.String, true, null) { example("Subtitle") example("A really long subtitle to test wrapping…") } }
  19. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) { description("Documentation about this property.") example("Title") example("A really long title to test this use case…") } optionalContentSubtitle() }
  20. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) { description("Documentation about this property.") example("Title") example("A really long title to test this use case…") } optionalContentSubtitle() }
  21. ++

  22. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) … optionalContent("subtitle", Type.String, nullable = true, default = null) }
  23. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) … optionalContent("subtitle", Type.String, nullable = true, default = null) minVersion(2) { } }
  24. Lona Spec DSL component("MyHeaderComponent") { description("Introduces sections of text. …")

    content("title", Type.String) … optionalContent("subtitle", Type.String, nullable = true, default = null) minVersion(2) { optionalContent("showDivider", Type.Boolean, nullable = false, default … } } }
  25. Lona Spec DSL minVersion(2) { component("MyOtherComponent") { … minVersion(3) {

    optionalContent(…) { … } } minVersion(4) { … } } } minVersion(3) { … }
  26. Lona JSON Specs { "components": [ { "type": "MyHeaderComponent", "content":

    [{ "nullable": false, "name": "title", "type": "String" }] }, … ], "version": 1 }
  27. Lona JSON Specs { "components": [ { "type": "MyHeaderComponent", "content":

    [{ "nullable": false, "name": "title", "type": "String" }] }, … ], "version": 1 }
  28. Lona JSON Specs { "components": [ { "type": "MyHeaderComponent", "content":

    [{ "nullable": false, "name": "title", "type": "String" }] }, … ], "version": 1 }
  29. Lona JSON Specs { "components": [ { "type": "MyHeaderComponent", "content":

    [{ "nullable": false, "name": "title", "type": "String" }] }, … ], "version": 1 }
  30. Lona JSON Specs { "components": [ { "type": "MyHeaderComponent", "content":

    [{ "nullable": false, "name": "title", "type": "String" }] }, … ], "version": 1 }
  31. Lona JSON Specs "examples": [ { "id": "0", "type": "MyHeaderComponent",

    "content": {"title": "Title"} }, { "id": "1", "type": "MyHeaderComponent", "content": {"title": "A really long title to test this use case…"} } ]
  32. Lona JSON Specs "examples": [ { "id": "0", "type": "MyHeaderComponent",

    "content": {"title": "Title"} }, { "id": "1", "type": "MyHeaderComponent", "content": {"title": "A really long title to test this use case…"} } ]
  33. Lona JSON Specs "examples": [ { "id": "0", "type": "MyHeaderComponent",

    "content": {"title": "Title"} }, { "id": "1", "type": "MyHeaderComponent", "content": {"title": "A really long title to test this use case…"} } ]
  34. Backend Lona specification JSON specs iOS Web frontend Android JSON

    schemas Humans Documentation Page builder Humans
  35. Lona Type-Unsafe Page Builder pageBuilder { componentInstance("MyHeaderComponent") { "title" to

    "Scaling Server-Driven UI with the Power of Kotlin" "subtitle" to "Bla bla bla" } componentInstance("MyOtherComponent") { … } … }
  36. Lona Type-Unsafe Page Builder pageBuilder { componentInstance("MyHeaderComponent") { "title" to

    "Scaling Server-Driven UI with the Power of Kotlin" "subtitle" to "Bla bla bla" } componentInstance("MyOtherComponent") { … } … }
  37. Lona Type-Unsafe Page Builder pageBuilder { componentInstance("MyHeaderComponent") { "title" to

    "Scaling Server-Driven UI with the Power of Kotlin" "subtitle" to "Bla bla bla" } componentInstance("MyOtherComponent") { … } … }
  38. Lona Type-Safe Page Builder componentInstance("MyHeaderComponent") { "title" to "Scaling Server-Driven

    UI with the Power of Kotlin" "subtitle" to "Bla bla bla" } myHeaderComponent( title = "Scaling Server-Driven UI with the Power of Kotlin", subtitle = "Bla bla bla" }
  39. Backend Lona specification JSON specs iOS Web frontend Android JSON

    schemas Humans Documentation Page builder Humans Backend
  40. Backend Lona specification JSON specs iOS Web frontend Android JSON

    schemas Humans Documentation Page builder Humans Backend
  41. Lona Spec Modules val myHeaderComponent = reusableComponent("MyHeaderComponent") { … }

    specModule(name = "plus") { add(myHeaderComponent.version(1)) }
  42. • Versioning • Keeping clients in sync • Scaling •

    Documentation Challenges of server-driven UI
  43. • Versioning • Keeping clients in sync • Scaling •

    Documentation Challenges of server-driven UI Kotlined
  44. • Versioning • Keeping clients in sync • Scaling •

    Documentation Challenges of server-driven UI Kotified?
  45. • Speed of iteration • Build once, deploy anytime •

    Consistency • Quality Server-driven UI with a Kotlin DSL
  46. Thank you and remember to vote! Laura Kelly @heylaurakelly Nathanael

    Silverman #KotlinConf Credit to vecteezy.com for the finger snap icon