πŸ€–πŸ Android + iOS: организация ΠΊΠΎΠ΄Π° прилоТСния с использованиСм Kotlin Multiplatform Mobile

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ простого прилоТСния (счСтчика) ΠΏΠΎΠ΄ ΠΎΠ±Π΅ ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Π΅ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π½Π° языкС Kotlin.

Если Π²Ρ‹ Π·Π°Π΄ΡƒΠΌΡ‹Π²Π°Π΅Ρ‚Π΅ΡΡŒ Π½Π°Π΄ созданиСм мобильного прилоТСния ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΠ΄ iOS ΠΈ Android, Π·Π½Π°ΠΊΠΎΠΌΡ‹ с языком Kotlin ΠΈ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ новСнькоС, Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Kotlin Multiplatform Mobile (KMM). Π­Ρ‚ΠΎ SDK (Π½Π°Π±ΠΎΡ€ инструмСнтов для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния) Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠ΅ΠΉ JetBrains (создатСля языка Kotlin), Π½Π΅Π΄Π°Π²Π½ΠΎ Π²Ρ‹ΡˆΠ΅Π΄ΡˆΠΈΠΉ Π² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΡƒΡŽ Π±Π΅Ρ‚Ρƒ, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, самоС врСмя ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Π΄Π΅Π»Π΅!

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ:

  • основныС особСнности KMM;
  • Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠ³ΠΎ KMM-прилоТСния;
  • ΠΏΡ€ΠΈΠ΅ΠΌΡ‹ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π°;
  • рСсурсы для дальнСйшСго изучСния.

Π§Ρ‚ΠΎ особСнного Π² KMM ΠΈ Ρ‡Π΅ΠΌ ΠΎΠ½ отличаСтся ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ?

Π―Π΄Ρ€ΠΎΠΌ KMM являСтся тСхнология Kotlin Native, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π°Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄, написанный Π½Π° языкС Kotlin, Π² платформонСзависимыС, Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ прилоТСния ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

Π‘Π°ΠΌΠΎΠ΅ Π²Π°ΠΆΠ½ΠΎΠ΅ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ популярных Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ для ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ React Native ΠΈΠ»ΠΈ Flutter, это Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ KMM прСдоставляСт Π½Π°Π±ΠΎΡ€ инструмСнтов, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ‰ΡƒΡŽ Π»ΠΎΠ³ΠΈΠΊΡƒ для ΠΎΠ±ΠΎΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² Π²ΠΈΠ΄Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, написанной Π½Π° языкС Kotlin, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π·Π°Ρ‚Π΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π² Android, Ρ‚Π°ΠΊ ΠΈ Π² iOS прилоТСния (рис. 1).

Рис.1. АрхитСктура KMM-прилоТСния

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΠ»ΡŽΡΡ‹ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°:

  • Π›Π΅Π³ΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ прилоТСния. Достаточно просто постСпСнно Π²Ρ‹Π΄Π΅Π»ΡΡ‚ΡŒ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ.
  • МСньший Ρ€Π°Π·ΠΌΠ΅Ρ€ прилоТСния. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡ ΠΊΠΎΠ΄Π° Kotlin Native добавляСт нСбольшой ΠΎΠ²Π΅Ρ€Ρ…Π΅Π΄, поэтому Ρ€Π°Π·ΠΌΠ΅Ρ€ прилоТСния ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ мСньшС Π°Π½Π°Π»ΠΎΠ³ΠΎΠ² Π½Π° Flutter ΠΈ React Native.
  • Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²Π°ΡˆΠΈΡ… iOS ΠΈ Android-прилоТСния, Π±Π΅Π· нСобходимости написания Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°.
  • ΠžΠ±Ρ‰ΠΈΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… прилоТСниях, Π½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ Π² Π²Π΅Π±-прилоТСниях, ΠΈ Π² сСрвСрной Π»ΠΎΠ³ΠΈΠΊΠ΅ Π½Π° Kotlin (рис. 2).
Рис. 2. ИспользованиС ΠΎΠ±Ρ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° ΠΌΠ΅ΠΆΠ΄Ρƒ сСрвСрной Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°ΠΌΠΈ ΠΈ web

Но Π½Π΅ стоит Π·Π°Π±Ρ‹Π²Π°Ρ‚ΡŒ ΠΈ ΠΎ минусах:

  • Высокий ΠΏΠΎΡ€ΠΎΠ³ Π²Ρ…ΠΎΠ΄Π°. НСобходимы Π±Π°Π·ΠΎΠ²Ρ‹Π΅ знания Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎΠ΄ iOS ΠΈ Android Π΄Π°ΠΆΠ΅ для создания простого прилоТСния.
  • НСбольшоС ΠΊΠΎΠΌΡŒΡŽΠ½ΠΈΡ‚ΠΈ. Π’Π°ΠΊ ΠΊΠ°ΠΊ KMM всС Π΅Ρ‰Π΅ находится Π² Π±Π΅Ρ‚Π΅, Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π½Π΅ Ρ‚Π°ΠΊΠΎΠ΅ большоС число ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ. Для сравнСния: Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ написания ΡΡ‚Π°Ρ‚ΡŒΠΈ вопросов с Ρ‚Π΅Π³ΠΎΠΌ Flutter Π² Stackoverflow большС 160 тысяч, Π° ΠΏΠΎ KMM – Ρ‡ΡƒΡ‚ΡŒ большС тысячи.
  • НСбольшоС количСство ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅Π½Π½Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ. НСсмотря Π½Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ стандартная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° языка Kotlin ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована Π² ΠΎΠ±Ρ‰Π΅ΠΌ ΠΊΠΎΠ΄Π΅ Π±Π΅Π· ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ языка Kotlin ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ платформозависимыС Π²Ρ‹Π·ΠΎΠ²Ρ‹ Java-ΠΊΠΎΠ΄Π° ΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ.
  • Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΠ±Ρ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π°. KMM Π½Π΅ прСдоставляСт Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ, ΠΊΠ°ΠΊ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ прилоТСния, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ ΠΎΠ±Ρ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° ΠΈ Π½Π΅ ΡƒΡΠ»ΠΎΠΆΠ½ΠΈΡ‚ΡŒ процСсс Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

Команда JetBrains Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π°Π΄ Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅ΠΌ ΠΊΠΎΠΌΡŒΡŽΠ½ΠΈΡ‚ΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠ»ΡƒΡ‡ΡˆΠ°Π΅Ρ‚ ΠΏΠ»Π°Π³ΠΈΠ½ для Android Studio, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°ΠΌΠ΅Ρ‚Π½ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ созданиС ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ KMM прилоТСния. А послСдний минус ΠΌΡ‹ рассмотрим ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π΄Π°Π»Π΅Π΅ ΠΈ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ популярный способ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ прилоТСния Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ максимально ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ Π·ΠΎΠ»ΠΎΡ‚ΠΎΠΌΡƒ ΠΏΡ€Π°Π²ΠΈΠ»Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ – DRY (don’t repeat yourself).

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° мобильного Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Β»

АрхитСктура Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠ³ΠΎ KMM-прилоТСния

АрхитСктура Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ прилоТСния – это ΠΌΠΎΠ½ΠΎΡ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ, состоящий ΠΈΠ· Ρ‚Ρ€Π΅Ρ… ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ: Android-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, iOS-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ общая Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° (рис. 3).

Рис. 3. Π‘Ρ…Π΅ΠΌΠ° ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ KMM прилоТСния

ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ с Ρ‚Π°ΠΊΠΎΠΉ структурой ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Π° для Android Studio. Π¨Π°Π³ΠΈ ΠΏΠΎ настройкС ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описаны Π½Π° сайтС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, поэтому ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠ³Π»ΡƒΠ±Π»ΡΡ‚ΡŒΡΡ Π² Π½Π΅Π³ΠΎ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ прСдстоит Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΊΠΎΠ΄. Но ΠΊΠ°ΠΊ ΠΆΠ΅ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ? Π’Π΅Π΄ΡŒ часто ΠΌΠ½ΠΎΠ³ΠΎ Π»ΠΎΠ³ΠΈΠΊΠΈ находится нСпосрСдствСнно Π² UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…, Π° Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ с Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠ΅ΠΉ? Π—Π΄Π΅ΡΡŒ Π½Π°ΠΌ Π½Π° ΠΏΠΎΠΌΠΎΡ‰ΡŒ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π½Ρ‹ΠΉ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ ΠΈΠ· Flutter, ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Π΅Π³ΠΎ создатСлями ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠ΅ΠΉ Google Π² 2018. Π­Ρ‚ΠΎΡ‚ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ называСтся BLoC (business-logic components) ΠΈ ΠΎΠ½ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ вынСсти всю бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΈΠ· UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π² ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ – BLoC (рис. 4).

Рис. 4. Визуализация ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ BLoC'ΠΎΠ²

Π’Π°ΠΊΠΈΠ΅ bloc’и тСсно связаны с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ UI-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ ΠΈ Π΅Π³ΠΎ ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ, ΠΎΠ½ΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΈ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°ΡŽΡ‚ΡΡ вмСстС с Π½ΠΈΠΌ. Но bloc’и Π½Π΅ зависят ΠΎΡ‚ Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ Π½Π΅ содСрТат Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ UI, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, ΠΎΠ½ΠΈ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Ρ‹ для помСщСния Π² ΠΎΠ±Ρ‰ΠΈΠΉ ΠΊΠΎΠ΄. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ Π»Π΅Π³ΠΊΠΎ Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΡƒΠΆΠ΅ созданы ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠΌΡŒΡŽΠ½ΠΈΡ‚ΠΈ. Бамая популярная ΠΈΠ· Π½ΠΈΡ… Π½Π° GitHub – Decompose, Π½Π° Π½Π΅ΠΉ ΠΌΡ‹ ΠΈ остановимся Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅.

Π”Π°Π²Π°ΠΉΡ‚Π΅ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ создания BLoC’а Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Decompose

Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° рассмотрим ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ счСтчик, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΌΠ΅Π΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒ ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Ρ‚ΡŒ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ.

ОпишСм бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ нашСго ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°:

  1. Он Ρ…Ρ€Π°Π½ΠΈΡ‚ состояниС – Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика.
  2. Π£ Π½Π΅Π³ΠΎ Π΅ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ для увСличСния значСния Π½Π° ΠΎΠ΄ΠΈΠ½.
  3. Π£ Π½Π΅Π³ΠΎ Π΅ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ значСния Π½Π° ΠΎΠ΄ΠΈΠ½.

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Kotlin-интСрфСйс с этой Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ Π² ΠΎΠ±Ρ‰Π΅ΠΌ ΠΌΠΎΠ΄ΡƒΠ»Π΅:

CounterComponent.kt
data class CounterState(val count: Int)

interface CounterComponent {
   val state: Value<CounterState> // (1)
   fun onIncrease() // (2)
   fun onDecrease() // (3)
}

Π­Ρ‚ΠΎ ΠΈ Π΅ΡΡ‚ΡŒ интСрфСйс нашСго bloc’а. Value – это ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ интСрфСйс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ прСдставляСт Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Decompose для хранСния состояния ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ интСгрируСтся со SwiftUI ΠΈ Jetpack Compose (Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌΠΈ iOS ΠΈ Android для UI).

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ CounterState, Π° Π½Π΅ просто Int, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΠ·-Π·Π° особСнностСй Kotlin Native, Value Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

НапишСм Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ для нашСго bloc’а:

CounterComponent.kt
class DefaultCounterComponent: CounterComponent {
    override val state = MutableValue(CounterState(0))
    override fun onIncrease() {
        state.reduce { it.copy(count = it.count + 1) }
    }
    override fun onDecrease() {
        state.reduce { it.copy(count = it.count - 1) }
    }
}

MutableValue Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс Value ΠΈ Ρ‚Π°ΠΊΠΆΠ΅ прСдоставляСтся Decompose. reduce – Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ хэлпСр, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° основС ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ наш bloc Π³ΠΎΡ‚ΠΎΠ² ΠΊ использованию Π² iOS ΠΈ Android-прилоТСниях.

Для Android-прилоТСния создадим простой ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π° Jetpack Compose (для простоты восприятия, всС ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ Π±Ρ‹Π»ΠΈ ΡƒΠ±Ρ€Π°Π½Ρ‹ ΠΈΠ· ΠΊΠΎΠ΄Π°):

CounterUi.kt
@Composable
fun CounterUi(counterComponent: CounterComponent) {
   val state by counterComponent.state.subscribeAsState()
   Column {
       Text(text = "${state.count}")
       Button(onClick = counterComponent::onIncrease) {
           Text(text = "+")
       }
       Button(onClick = counterComponent::onDecrease) {
           Text(text = "-")
       }
   }
}

subsribeAsState() – Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ позволяСт Ρ‚Ρ€Π°Π½ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Value Π² State, Ρ‚Π°ΠΊΠΆΠ΅ прСдоставляСтся Decompose

Для простоты, наш счСтчик – СдинствСнный ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прилоТСния, поэтому ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ наш bloc Π² MainActivity

MainActivity.kt
class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)

       val counterComponent = DefaultCounterComponent()

       setContent {
           CounterUi(counterComponent)
       }
   }
}

ΠŸΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ iOS-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ Π½Π° SwiftUI:

CounterView.swift
import SwiftUI
import shared // наша общая Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

struct CounterView: View {

   private let component: CounterComponent

   @ObservedObject
   private var state: ObservableValue<CounterState>

   init(_ component: CounterComponent) {
       self.component = component
       state = ObservableValue<CounterState>(component.state)
   }

   var body: some View {
       HStack {
           Text("\(state.value.count)")
           Button(action: { component.onIncrease() }) {
               Text("+")
           }
           Button(action: { component.onDecrease() }) {
               Text("-")
           }
       }
   }
}

Код Π½Π΅ сильно отличаСтся ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π» Π² Android: для отслСТивания ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Value ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ – ObservableValue, ΠΊΠΎΠ΄ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ· ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ рСпозитория Decompose.

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ bloc Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния:

iOSApp.swift
@main
struct iOSApp: App {
  var counterComponent = DefaultCounterComponent()

  var body: some Scene {
     WindowGroup {
        CounterView(counterComponent)
     }
  }
}

НашС KMM ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅-счСтчик Π³ΠΎΡ‚ΠΎΠ²ΠΎ. Вся бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° находится Π² ΠΎΠ±Ρ‰Π΅ΠΌ ΠΌΠΎΠ΄ΡƒΠ»Π΅ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ совмСстно iOS- ΠΈ Android-частями.

Код Π½Π° Π“ΠΈΡ‚Ρ…Π°Π±Π΅
Код ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ прилоТСния ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.

Π§Ρ‚ΠΎ Π΅Ρ‰Π΅ прСдоставляСт Decompose?

Π’ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΠΊΠΎΡΠ½ΡƒΠ»ΠΈΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ самого Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. ΠšΡ€ΠΎΠΌΠ΅ Π½Π΅Π³ΠΎ, Decompose содСрТит инструмСнты для Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ экранами, сохранСния состояния ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ Back для Android

ΠŸΠΎΠ»Π΅Π·Π½Ρ‹Π΅ рСсурсы для изучСния Kotlin Multiplatform Mobile

  1. ΠžΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ get-started ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ JetBrains
  2. Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° KMM
  3. ДокумСнтация Decompose
  4. ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ IceRock
  5. Поиск Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ для KMM

Π•Π²Π³Π΅Π½ΠΈΠΉ Π₯ΠΎΡ…Π»ΠΎΠ² Tech Lead Π² ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Chatfuel

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
13 фСвраля 2018

10 ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°ΡƒΡ‡Π°Ρ‚ вас ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ

Π˜Ρ‰Π΅Ρ‚Π΅ курсы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°ΡƒΡ‡Π°Ρ‚ вас ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ? ΠœΡ‹ собрали Π»ΡƒΡ‡ΡˆΠΈΠ΅ ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹...
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
11 июня 2017

20 ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹Ρ… рСсурсов для изучСния Kotlin

Данная ΠΏΠΎΠ΄Π±ΠΎΡ€ΠΊΠ° ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² связана с ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π½ΠΎΠ²ΠΎΠ³ΠΎ, ΠΈ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΡƒΠΆΠ΅ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»...