Kotlin For Swift Developers - Swift Paris, October 2018

Kotlin For Swift Developers - Swift Paris, October 2018

Kotlin is a new language born on the JVM that's gained a ton of popularity with Android developers. Learn about its similarities and differences with Swift, and some new, crazy things you can do with Kotlin/Native (and some totally sane things you can't do).

Sandbox app mentioned in the talk: https://github.com/designatednerd/KotlinNativeTest

C4861b1dfdf3bbb21faec4a1acdf183d?s=128

Ellen Shapiro

October 24, 2018
Tweet

Transcript

  1. KOTLIN FOR SWIFT DEVELOPERS SWIFT PARIS | PARIS, FRANCE |

    OCTOBER 2018 @DESIGNATEDNERD | BAKKENBAECK.COM | JUSTHUM.COM
  2. KOTLIN POUR SWIFT DEVELOPPEURS SWIFT PARIS ! PARIS, FRANCE OCTOBRE

    2018 @DESIGNATEDNERD ! BAKKENBAECK.COM JUSTHUM.COM
  3. !"

  4. None
  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. ✨ " ☕

  12. None
  13. WHAT IS KOTLIN ?

  14. None
  15. None
  16. None
  17. None
  18. WHY SHOULD I CARE?

  19. None
  20. None
  21. A CONSTANT STRING

  22. SWIFT let greeting = "Hello World"

  23. SWIFT let greeting = "Hello World" KOTLIN val greeting =

    "Hello World"
  24. AN OPTIONAL INTEGER VARIABLE

  25. SWIFT var something: Int?

  26. SWIFT var something: Int? KOTLIN var something: Int?

  27. ☠ NullPointerException

  28. !"

  29. GENERICS AND FUNCTIONS AS PARAMETERS

  30. SWIFT func useFunction<T, U>(on item: T, function: (T) -> U)

    -> U { return function(item) } func insertExclamationPoint(in string: String) -> String { return string .components(separatedBy: " ") .joined(separator: "! ") } let result = useFunction(on: "try Swift", function: insertExclamationPoint(in:)) // result: "try! Swift"
  31. KOTLIN fun <T, U>T.useFunction(action: (T) -> U): U { return

    action(this) } fun insertExclamationPoint(in: String) : String { return in.split(" ").joinToString("! ") } val result = "try Kotlin".useFunction { insertExclamationPoint(it) } // result: "try! Kotlin"
  32. map filter reduce

  33. map filter reduce*

  34. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(0, +) // reduced: 6
  35. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(0, +) // // reduced: 6
  36. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(0) { $0 + $1 } // reduced: 6
  37. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(20) { $0 + $1 } // reduced: 26
  38. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(20) { $0 + $1 } // reduced: 26 KOTLIN val numbers = arrayOf(1, 2, 3) val reduced = numbers.reduce { total, current -> total + current } // reduced: 6
  39. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(20) { $0 + $1 } // reduced: 26 ⬆ KOTLIN val numbers = arrayOf(1, 2, 3) val reduced = numbers.reduce { total, current -> total + current } // reduced: 6
  40. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(20) { $0 + $1 } // reduced: 26 KOTLIN val numbers = arrayOf(1, 2, 3) val folded = numbers.fold(20) ⬅ { total, current -> total + current } // folded: 26
  41. SWIFT let doubled = [ 1, 2, 3 ].map {

    $0 * 2 }
  42. SWIFT let doubled = [ 1, 2, 3 ].map {

    $0 * 2 } KOTLIN arrayOf(1, 2, 3).map { it * 2 }
  43. None
  44. None
  45. SWIFT let doubled = [ 1, 2, 3 ].map {

    $0 * 2 } KOTLIN arrayOf(1, 2, 3).map { it * 2 }
  46. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(20) { $0 + $1 } // reduced: 26
  47. $0 $1 $2...$∞

  48. SWIFT let numbers = [ 1, 2, 3 ] let

    reduced = numbers.reduce(20) { $0 + $1 } // reduced: 26 KOTLIN val numbers = arrayOf(1, 2, 3) val folded = numbers.fold(20) { total, current -> total + current } // folded: 26 ⬆
  49. None
  50. !"#

  51. None
  52. guard

  53. NOW (KOTLIN) optionalThing?.let { it.doSomething() }

  54. NOW (KOTLIN) optionalThing?.let { it.doSomething() } else { doSomethingElse() }

  55. NOW (KOTLIN) optionalThing?.let { it.doSomething() } else { // !

    Not possible doSomethingElse() }
  56. NOW (KOTLIN) if (optionalThing != nil) { optionalThing.doSomething() } else

    { doSomethingElse() }
  57. NOW (KOTLIN) if (optionalThing != nil) { optionalThing.doSomething() //<- magic

    unwrap!! } else { doSomethingElse() }
  58. PROPOSED (KOTLIN) guard val thing = optionalThing else { return

    } thing.doSomething()
  59. apply

  60. NOW (SWIFT) UserDefaults.standard.set(true, forKey: "DefaultOne") UserDefaults.standard.set(false, forKey: "DefaultTwo)

  61. NOW (BETTER SWIFT) let defaults = UserDefaults.standard defaults.set(true, forKey: "DefaultOne")

    defaults.set(false, forKey: "DefaultTwo)
  62. PROPOSED (SWIFT) UserDefaults.standard.apply { "DefaultOne" = true, "DefaultTwo" = false,

    }
  63. PROTOCOLS WITH DEFAULT IMPLEMENTATIONS

  64. None
  65. PROPOSED (KOTLIN) interface SomeInterface { fun doAThing() }

  66. PROPOSED (KOTLIN) interface SomeInterface { fun doAThing() } @DefaultImpl SomeInterface

    { fun doAThing() { println("Hi, I'm the default implementation!") } }
  67. @JVMDefault + DefaultImpl (SORT OF)

  68. SEALED CLASSES

  69. KOTLIN sealed class ViewState { class Empty(val placeholder: View): ViewState()

    class HasContent(val items: List<Item>): ViewState() }
  70. KOTLIN sealed class ViewState { class Empty(val placeholder: View): ViewState()

    class HasContent(val items: List<Item>): ViewState() } when (state) { is ViewState.Empty --> display(it.placeholder) is ViewState.HasContent --> adapter.reloadWith(it.items) }
  71. SWIFT enum TableViewState { case empty(placeholderView: UIView) case loaded(items: [Item])

    } switch state { case .empty(let placeholder): display(placeholder) case .hasContent(let items): dataSource.reloadWith(items) }
  72. KOTLIN sealed class ViewState { class Empty(val placeholder: View): ViewState()

    class HasContent(val items: List<Item>): ViewState() }
  73. KOTLIN sealed class ViewState { class Empty(val placeholder: View): ViewState()

    class HasContent(val items: List<Item>): ViewState() { val adapter = RecyclerViewAdapter(items) fun selectedItem(item: Item) { // Do something ith the selected item } } }
  74. None
  75. None
  76. KOTLIN / NATIVE

  77. None
  78. PLUS ÇA CHANGE

  79. LLVM

  80. LLVM

  81. LLVM

  82. SUPPORTED PLATFORMS ▸ x86_64 (macOS, iOS Sim, Linux, Windows) ▸

    arm64 (iOS, Android) ▸ arm32 (iOS, Android, Linux) ▸ arm32 hardfp (Raspberry Pi) ▸ MIPS (Linux) ▸ wasm32 (Web Assembly)
  83. None
  84. None
  85. None
  86. None
  87. expect fun

  88. None
  89. None
  90. None
  91. KOTLIN IOS LIBRARY ! WRAPPERS

  92. None
  93. None
  94. None
  95. KOTLIN IOS LIBRARY ! WRAPPERS* *(WHICH USUALLY WORK)

  96. KOTLIN / NATIVE val decoded = NSString.create( data = data,

    encoding = NSUTF8StringEncoding )
  97. KOTLIN / NATIVE val decoded = NSString.create( data = data,

    encoding = NSUTF8StringEncoding ) // `decoded` type: NSString
  98. None
  99. None
  100. None
  101. None
  102. None
  103. None
  104. BUSINESS LOGIC

  105. None
  106. None
  107. KOTLIN / NATIVE GOTCHAS

  108. !

  109. + =

  110. MEMORY MANAGEMENT AND CONCURRENCY !!!!!!!

  111. COROUTINES

  112. COROUTINES* * ONLY WORK ON THE MAIN THREAD IN KOTLIN

    / NATIVE
  113. (˽s̕s҂˽Ɨ ˍʓˍ

  114. Worker

  115. ! MONOREPO

  116. https://github.com/designatednerd/ KotlinNativeTest

  117. OBJ-C INTEROP HILARITY

  118. SWIFT: ENUMS enum Things { case monday case tuesday case

    wednesday case thursday case friday case saturday case sunday }
  119. KOTLIN: ENUM CLASSES enum class DayOfWeek { Monday, Tuesday, Wednesday,

    Thursday, Friday, Saturday, Sunday; }
  120. None
  121. A KOTLIN ENUM CLASS IN A KOTLIN / NATIVE FRAMEWORK

  122. A KOTLIN ENUM CLASS IN A KOTLIN / NATIVE FRAMEWORK

  123. A KOTLIN ENUM CLASS IN A KOTLIN / NATIVE FRAMEWORK

  124. SWIFT SWITCHING ON A KOTLIN ENUM switch day { case

    .monday: print("You can fall apart") case .tuesday, .wednesday: print("Break my heart") case .thursday: print("Doesn't even start") case .friday: print("I'm in love") case .saturday: print("Wait") case .sunday: print("Always comes too late") } // ! Seems legit...
  125. SWIFT SWITCHING ON A KOTLIN ENUM switch day { case

    .monday: print("You can fall apart") case .tuesday, .wednesday: print("Break my heart") case .thursday: print("Doesn't even start") case .friday: print("I'm in love") case .saturday: print("Wait") case .sunday: print("Always comes too late") } // ! ERROR: ! Switch must be exhaustive
  126. SWIFT SWITCHING ON A KOTLIN ENUM switch day { case

    .monday: print("You can fall apart") case .tuesday, .wednesday: print("Break my heart") case .thursday: print("Doesn't even start") case .friday: print("I'm in love") case .saturday: print("Wait") case .sunday: print("Always comes too late") default: fatalError("Not a day") // ! }
  127. DOCUMENTATION

  128. DOCUMENTATION? ¯\_(ϑ)_/¯

  129. None
  130. PRODUCTION?!

  131. KOTLIN: ☕ OR " =

  132. try? kotlin

  133. https://try.kotlinlang.org

  134. None
  135. None
  136. EDU TOOLS PLUGIN FOR INTELLIJ OR ANDROID STUDIO

  137. None
  138. None
  139. OBLIGATORY SUMMARY SLIDE

  140. OBLIGATORY SUMMARY SLIDE ▸ Literally put the fun in functional

    programming
  141. OBLIGATORY SUMMARY SLIDE ▸ Literally put the fun in functional

    programming ▸ Make Friends With Android
  142. OBLIGATORY SUMMARY SLIDE ▸ Literally put the fun in functional

    programming ▸ Make Friends With Android ▸ Kotlin Native Could Be A Whole New World
  143. OBLIGATORY SUMMARY SLIDE ▸ Literally put the fun in functional

    programming ▸ Make Friends With Android ▸ Kotlin Native Could Be A Whole New World ▸ try! Kotlin
  144. ONE MORE THING

  145. ONE MORE THING: (A SHAMELESS PLUG!)

  146. None
  147. ! MERÇI!

  148. LINKS! ▸ Kotlin Home & Documentation: https://kotlinlang.org ▸ Kotlin Native

    MultiplatformApp tutorial https://kotlinlang.org/docs/tutorials/ native/mpp-ios-android.html ▸ KotlinConf iOS App in Kotlin/Native: https://github.com/JetBrains/kotlinconf- app/tree/master/konfios
  149. MORE LINKS! ▸ The Edu Tools Plugin for IntelliJ or

    Android Studio https://kotlinlang.org/docs/tutorials/ edu-tools-learner.html ▸ Representing State (KotlinConf talk on Sealed Classes) https://www.youtube.com/watch?v=- lVVfxsRjcY ▸ Sealed Classes Opened My Mind (KotlinConf Talk) https://www.youtube.com/watch? v=uGMm3StjqLI
  150. SHAMELESS SELF-PROMOTION! ▸ My talk on Protocol-Oriented Programming from Dot

    Swift https://www.dotconferences.com/2018/01/ ellen-shapiro-protocols-all-the-way-down ▸ Kotlin Apprentice https://store.raywenderlich.com/products/ kotlin-apprentice ▸ Android Apprentice https://store.raywenderlich.com/products/ android-apprentice
  151. ILLUSTRATION CREDITS ▸ Monica Komperda, Native Code Forever (Hire her!

    She's awesome!) http://mokomperda.com/design