Skip to content

Commit 57c533e

Browse files
authored
Merge pull request #160 from maiow/docusaurus
Update onboarding, university
2 parents f1a6baa + 983c2af commit 57c533e

File tree

19 files changed

+656
-172
lines changed

19 files changed

+656
-172
lines changed
232 KB
Loading

learning/android/navigation.md

Lines changed: 459 additions & 3 deletions
Large diffs are not rendered by default.

learning/kotlin-multiplatform/mobile-highlights.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ sidebar_position: 2
2020
4. Разница extensions - [раз](../kotlin-native/swift-extensions), [два](https://medium.com/mobile-app-development-publication/kotlin-vs-swift-the-extension-5462b531260b);
2121
5. [Абстрактные классы](https://medium.com/mobile-app-development-publication/kotlin-vs-swift-the-abstract-class-f8817e5e54f).
2222

23-
## Kotlin + Swift IDE
24-
25-
AppCode позволяет разрабатывать и Kotlin и Swift код одновременно. [Видео с демонстрацией](https://www.youtube.com/watch?v=ELfcPdWP_CY)
26-
2723
## Конфликты имен на iOS
2824

2925
- В iOS у всех объектов есть поле `description` (работает также как Kotlin `toString`) и поэтому при использовании в Kotlin свойств с таким названием будет появляться в iOS дополнительное поле `_description` - которое и будет свойством от Kotlin

learning/state.md

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,4 +361,85 @@ _actions.trySend(State.Empty)
361361
- `trySend` же возвращает `Boolean`: `true` - если добавить новое значение удалось, `false` - если не удается добавить из-за превышения объема буфера значений. Это значит что если в очереди уже есть какие-то события, которые не успел получить UI, то новое просто будет утерено. Поэтому всегда следует использовать `send`.
362362

363363
## Дополнительно
364-
Для работы с событиями и состояниями у нас в компании используются возможности библиотеки [moko-mvvm](https://github.com/icerockdev/moko-mvvm). С ее помощью происходят привязки, как односторонняя, так и двусторонняя. Событиями занимается класс EventsDispatcher.
364+
Для работы с событиями и состояниями у нас в компании используются возможности библиотеки [moko-mvvm](https://github.com/icerockdev/moko-mvvm). С ее помощью происходят привязки, как односторонняя, так и двусторонняя.
365+
366+
Ранее событиями занимался класс EventsDispatcher. Подход с использованием EventsDispatcher считается устаревшим и в новых проектах мы его не используем. Ниже справочная информация на случай, если встретитесь с ним.
367+
368+
`EventDispatcher` - это класс с одной единственной задачей - гарантировать доставку события и вызов его обработчика на UI, после сигнала от `ViewModel`.
369+
370+
Во `ViewModel` объявляется интерфейс с методами, реализация которых ей нужна на платформе, например, метод для перехода на какой-нибудь экран:
371+
372+
```kotlin
373+
interface EventsListener {
374+
fun routeToMainPage()
375+
}
376+
```
377+
378+
Далее, все что остается сделать, чтобы вызвать событие на `UI` - это получить во `ViewModel` объект `eventsDispatcher` и, когда пора переходить на главный экран, послать платформе это событие простым вызовом метода:
379+
```kotlin
380+
class EventsViewModel(
381+
val eventsDispatcher: EventsDispatcher<EventsListener>
382+
) : ViewModel() {
383+
384+
fun onButtonPressed() {
385+
eventsDispatcher.dispatchEvent { routeToMainPage() }
386+
}
387+
388+
interface EventsListener {
389+
fun routeToMainPage()
390+
}
391+
}
392+
```
393+
394+
На платформах `Fragment` и `UIViewController` реализуют этот интерфейс.
395+
Пример реализации на Android:
396+
397+
```kotlin
398+
class EventsFragment: Fragment(R.layout.fragment_simple), EventsViewModel.EventsListener {
399+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
400+
super.onViewCreated(view, savedInstanceState)
401+
402+
val viewModel: EventsViewModel = getViewModel {
403+
EventsViewModel(eventsDispatcherOnMain())
404+
}
405+
406+
viewModel.eventsDispatcher.bind(lifecycleOwner = this, listener = this)
407+
}
408+
409+
override fun routeToMainPage() {
410+
TODO("some routing")
411+
}
412+
}
413+
```
414+
415+
Пример на iOS:
416+
417+
```swift
418+
class EventsViewController: UIViewController {
419+
private var viewModel: EventsViewModel!
420+
421+
override func viewDidLoad() {
422+
super.viewDidLoad()
423+
424+
viewModel = EventsViewModel(
425+
eventsDispatcher: EventsDispatcher(listener: self)
426+
)
427+
}
428+
}
429+
430+
extension EventsViewController: EventsViewModelEventsListener {
431+
func routeToMainPage() {
432+
fatalError("some routing")
433+
}
434+
}
435+
```
436+
437+
За счет интерфейса обе платформы знают, какой набор действий должны поддерживать.
438+
Если во `ViewModel` нужно будет добавить еще одно событие, и мы забудем реализовать его на какой-нибудь из платформ, компилятор выделит, что отсутствует реализация метода интерфейса.
439+
440+
:::warning
441+
442+
В `dispatchEvent` нельзя передавать лямбду из общего кода, например, для установки действия по кнопке в [AlertDialog](https://developer.android.com/reference/android/app/AlertDialog). Нельзя этого делать потому, что на Android мы не сможем ее никуда сохранить, поэтому при пересоздании экрана она пропадет.
443+
Если вам нужно установить чему-либо на платформе действие - делайте соответствующий метод во `ViewModel`.
444+
445+
:::

onboarding/moko.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,19 @@ sidebar_position: 5
44

55
# MOKO библиотеки
66

7+
MOKO - это разработанные в компании мультиплатформенные open-source библиотеки, которые позволяют нам решать типовые задачи проще и быстрее.
78
Все наши проекты строятся с использованием библиотек MOKO, поэтому нужно поближе познакомиться с MOKO библиотеками.
89

9-
- Материалы [о MOKO в целом](../learning/libraries/moko)
10-
- Материалы [о MOKO resources](../learning/libraries/moko/moko-resources)
11-
- Материалы [о MOKO MVVM](../learning/libraries/moko/moko-mvvm)
12-
- Материалы [о MOKO units](../learning/libraries/moko/moko-units)
13-
- Материалы [о MOKO paging](../learning/libraries/moko/moko-paging)
10+
В каждом репозитории MOKO-библиотеки находятся:
11+
- `README` с инструкцией по подключению и описанием использования библиотеки
12+
- `sample-проект` с практическим применением библиотеки. Вы можете склонировать себе репозиторий библиотеки и запустить `sample-app`
13+
- `Issues` - список обнаруженных ошибок в работе библиотеки, а также предложения по обновлению библиотеки. Если вы заметите ошибку в работе какой-либо MOKO-библиотеки или у вас есть предложение по изменению существующей - зафиксируйте свои мысли в `issue`
14+
15+
Посмотрите обзорную презентацию из материалов [о MOKO в целом](../learning/libraries/moko).
16+
Изучите библиотеку [MOKO resources](https://kmm.icerock.dev/university/icerock-basics/resources-in-common#библиотека-moko-resources), [дополнение](../learning/libraries/moko/moko-resources).
17+
18+
Также ознакомьтесь с:
19+
- использованием классов-оберток [CFlow и CStateFlow](https://kmm.icerock.dev/university/icerock-basics/mvvm#flow-c-moko-kswift) из [MOKO MVVM](../learning/libraries/moko/moko-mvvm)
20+
- использованием [mvvm-state](https://kmm.icerock.dev/university/lists/moko-paging#moko-mvvm-state) из MOKO MVVM
21+
- зачем нужна библиотека [МОКО Network](https://kmm.icerock.dev/learning/libraries/moko/moko-network)
22+
- видео [о MOKO paging](https://kmm.icerock.dev/learning/libraries/moko/moko-paging), конкретные примеры текущего применения стоит смотреть в текущих проектах.

onboarding/project-inside.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ mokoNetwork {
571571
572572
![mpp-library-](project-inside/project-inside-mpp-lib-src.png)
573573
574-
- `androidMain` - директория, содержащая файл `AndroidManifest.xml`, в котором объявляется идентификатор (уникальный!) для модуля `mpp-library` для Android-приложения;
574+
- `androidMain` - директория, содержащая платформенный di модуль. Ранее в проектах здесь находился файл `AndroidManifest.xml`, в котором объявлялся уникальный идентификатор для модуля `mpp-library` для Android-приложения. В новых проектах этого файла нет, т.к. id сейчас прописывается в рамках build.gradle.kts модуля;
575575
- `api` - директория, содержащая файл для генерации методов взаимодействия с API;
576576
- директория `commonMain` содержит директорию `kotlin`, в которой как раз и пишется вся бизнес-логика приложения; в директории `resources` находятся ресурсы, попавшие в проект через [moko-resources](https://github.com/icerockdev/moko-resources);
577577
- `commonTest` - директория, в которой находится исходный код тестов для общей библиотеки;

university/1-android-basics/app-logic.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ CodeLab [Get data from the internet](https://developer.android.com/codelabs/basi
4444

4545
Разные классы приложения должны между собой связываться. Чтобы связанность классов не стала слишком жесткой, что усложнит поддержку кода, используют паттерн Dependency Injection.
4646

47-
Подробнее позволит разобраться статья [Dependency Injection](https://developer.android.com/training/dependency-injection) и CodeLab [Using Hilt in your Android app](https://developer.android.com/codelabs/android-hilt).
47+
Подробнее позволит разобраться статья [Dependency Injection](https://developer.android.com/training/dependency-injection) и [Koin in Android app tutorial](https://insert-koin.io/docs/quickstart/android/).

university/1-android-basics/user-interface.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ sidebar_position: 4
110110

111111
А также многое про удобство можно прочитать на сайте [material.io](https://material.io/design) - разделы Interaction и Communication очень детально и наглядно объясняют как можно создавать комфортное использование приложения. Многие принципы применимы не только на android, но и на любой системе с UI.
112112

113+
## Изменения конфигурации
114+
115+
Некоторые конфигурации мобильных устройств могут измениться во время работы приложения. Это могут быть, например, ориентация экрана при повороте устройства пользователем, увеличение пользователем размера шрифта, смена локализации, смена темного режима на светлый и наоборот. В процессе создания приложения нужно помнить о необходимости обработки изменений конфигурации. Прочитайте [документацию Google](https://developer.android.com/guide/topics/resources/runtime-changes) про обработку смены конфигурации.
116+
113117
## Practice time
114118

115119
Сделать приложение по [дизайну](https://www.figma.com/file/07E2agIcfVsAZBMoq91ccL/android-ui-education).
@@ -123,3 +127,4 @@ sidebar_position: 4
123127
1. На фрагменте `ContactsFragment` расположить `RecyclerView` отрисовывающий множество элементов - разные контакты
124128
1. На фрагменте `ContactFragment` с помощью `ConstraintLayout` сверстать UI экрана просмотра контакта
125129
1. С помощью Android Navigation Component сделать переходы между списком и просмотром контакта
130+
1. Удостовериться в том, что приложение корректно обрабатывает смену конфигурации: локализации, темы, ориентации экрана, увеличение шрифта

university/3-kotlin-multiplatform-mobile/kmm-intro.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22
sidebar_position: 0
33
---
44

5-
# Введение в KMM
5+
# Введение в KMP
66

7-
Kotlin Multiplatform Mobile - это технология, позволяющая использовать единую базу кода для бизнес-логики приложений. Для каждой платформы код нужно писать только там, где это необходимо, например, для реализации пользовательского интерфейса или при работе с API конкретной платформы.
7+
Kotlin Multiplatform - это технология, позволяющая использовать единую базу кода для бизнес-логики приложений. Для каждой платформы код нужно писать только там, где это необходимо, например, для реализации пользовательского интерфейса или при работе с API конкретной платформы.
88

99
После прохождения этого раздела вы узнаете следующее
10-
- Для чего нужен Kotlin Multiplatform Mobile
10+
- Для чего нужен Kotlin Multiplatform
1111
- Что такое `expect/actual`
1212
- Работа с сетью используя Ktor
1313
- Сериализация данных при помощи Kotlin Serialization
14-
- Как настроить gradle для работы с KMM
14+
- Как настроить gradle для работы с KMP
1515
- Что такое multiplatform-settings и как их использовать
16+
- Как использовать библиотеку Koin для внедрения зависимостей в KMP
1617
- Что такое multiplatform библиотеки и их отличия от других библиотек
17-
- Где искать и как выбирать kmm библиотеки
18+
- Где искать и как выбирать KMP библиотеки
1819

1920
:::info
2021
Если вы уже знакомы со всем этим, можете переходить к [практическому заданию](practice)
21-
:::
22+
:::
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
sidebar_position: 6
3+
---
4+
5+
# Koin
6+
7+
[Koin](https://github.com/InsertKoinIO/koin) - это мультиплатформенная библиотека для внедрения зависимостей.<br/>Ранее в разделе Основы разработки Android приложений в Логике приложений/Dependency Injection вы уже проходили тьюториал по подключению Koin в Android.
8+
9+
[Официальная документация Koin](https://insert-koin.io), к ней следует обращаться за поиском информации по конкретному вопросу.
10+
11+
Рекомендуем ознакомиться со следующими разделами:
12+
1. Раздел Setup
13+
1. Раздел Core&Tests
14+
1. Раздел Android
15+
1. [Раздел Dependency Injection in Ktor](https://insert-koin.io/docs/reference/koin-ktor/ktor)
16+
17+
## Практическое задание
18+
Выполните действия по тьюториалу [Koin для KMP Dependency Injection](https://insert-koin.io/docs/reference/koin-mp/kmp).

0 commit comments

Comments
 (0)