апдейты в спринт 17

This commit is contained in:
andrew mayer
2025-06-07 13:07:59 +04:00
parent caf20dd1c3
commit f20950f601
6 changed files with 157 additions and 126 deletions
@@ -18,7 +18,7 @@ class ViewController: UIViewController {
}
```
> Если вы используете паттерн MVVM — разместите данные в `ViewModel` и свяжите её с `View` реактивным способом. Данные находятся в `ViewController`.
> Если вы используете паттерн MVVM — разместите данные в `ViewModel` и свяжите её с `View` реактивным способом. Данные находятся в `ViewController`.
**[ТУТ КАРТИНКА из папки Images с названием UISeachController01]**
@@ -1,6 +1,6 @@
За концепцию программы в мобильной команде отвечает продакт-менеджер. Он должен быть уверен в том, что продукт не только интересен пользователям, но и выполняет все необходимые функции. В больших проектах каждое пользовательское действие анализируется, чтобы делать выводы и определять, как дальше развивать приложение. Продакт-менеджер может самостоятельно анализировать, как конечные пользователи взаимодействуют с приложением (например, проводить интервью и спрашивать, что им нравится и что не нравится), либо обратиться за помощью к специалисту по аналитике.
> Пока вы проходите этот курс, команда Практикума анализирует ваши действия и собирает обратную связь, чтобы улучшать образовательный опыт. Если вы тоже хотите научиться анализировать данные пользователей, обратите внимание [курс Практикума по анализу данных (https://practicum.yandex.ru/data-analyst/)].
> Пока вы проходите этот курс, команда Практикума анализирует ваши действия и собирает обратную связь, чтобы улучшать образовательный опыт. Если вы тоже хотите научиться анализировать данные пользователей, обратите внимание [курс Практикума по анализу данных (https://practicum.yandex.ru/data-analyst/)].
Давайте разберёмся, что же такое аналитика продукта и как её использовать в наших приложениях. В этой теме будет немного теории, а также практические задачи. Они познакомят вас с тем, что обычно требуется от разработчиков в процессе анализа продукта.
@@ -1,13 +1,30 @@
Привет! Теперь, когда вы знаете, для чего нужна AppMetrica и как она устроена, пора добавить её в EmojiMixer. Если вы посмотрите [официальную документацию AppMetrica](https://appmetrica.yandex.ru/docs/mobile-sdk-dg/ios/ios-quickstart.html) — увидите несколько способов подключения библиотеки к проекту:
# Добавление зависимостей: SPM и Cocoapods
Привет! Теперь, когда вы знаете, для чего нужна AppMetrica и как она устроена, пора добавить её в EmojiMixer. Если вы посмотрите [официальную документацию AppMetrica](https://appmetrica.yandex.ru/docs/ru/sdk/ios/analytics/quick-start) — увидите несколько способов подключения библиотеки к проекту:
- Cocoapods,
- Carthage,
- SPM.
- SPM,
- и др.
Вы можете выбрать один из этих инструментов для управления зависимостями в вашем проекте. Тут стоит отметить, что **нельзя использовать оба менеджера одновременно для одной и той же библиотеки**, так как это приведет к конфликтам и ошибкам сборки. Выберите инструмент лучше всего подходящий для ваших нужд и опыта.
В настоящее время Swift Package Manager (SPM) является основным рекомендуемым инструментом для управления зависимостями в iOS-проектах. Но Cocoapods остается доступным вариантом, особенно для проектов, которые уже его используют, или для библиотек, которые ещё не поддерживают SPM.
Поскольку вы уже знакомы с Swift Package Manager (SPM) по предыдущим урокам, вы можете предпочесть его. Подробную инструкцию по добавлению AppMetrica с помощью SPM можно найти в [официальной документации на закладке "SPM в Xcode"](https://appmetrica.yandex.ru/docs/ru/sdk/ios/analytics/quick-start?tabs=defaultTabsGroup-gpclvrhj_spm%2520%25d0%25b2%2520xcode).
Кратко, шаги для добавления AppMetrica через SPM следующие:
1. В Xcode откройте ваш проект.
2. Перейдите в меню File -> Add Packages...
3. В появившемся окне в поле поиска справа вверху введите URL репозитория AppMetrica: `https://github.com/yandexmobile/metrica-sdk-ios`.
4. Xcode найдет пакет. Выберите `metrica-sdk-ios` и нажмите "Add Package".
Если вы решили использовать SPM для добавления AppMetrica, вы можете пропустить оставшуюся часть этого урока, посвященную Cocoapods, и сразу переходить к следующему.
## Что такое Cocoapods
Вы уже [встречались](**Ссылка: 11.1.1 Менеджеры зависимостей**) c менеджерами зависимостей в курсе. Давайте поговорим более подробно о Cocoapods, их достоинствах и недостатках.
# Что такое Cocoapods
Cocoapods - это менеджер зависимостей для проектов на языке Swift и Objective-C для платформ Apple. Он позволяет управлять зависимостями в вашем проекте, установить необходимые библиотеки и обновлять их до последней версии. Вы можете так же задать правила обновления версий, если они есть. Об этом мы поговорим немного позже
Если коротко описать принцип работы с Cocoapods, то он сводится к следующим шагам:
@@ -17,13 +34,13 @@ Cocoapods - это менеджер зависимостей для проект
Podfile создается всего один раз для проекта, так что работа сводится к минимуму. В чем преимущества и недостатки Cocoapods по сравнению с SPM? Давайте посмотрим:
# Плюсы
## Плюсы
- Большее количество библиотек по сравнению с SPM
- CocoaPods не только загружает библиотеки, но еще и интегрирует их в проект
- Поддержка Swift и Objective-C: Cocoapods поддерживает проекты на языке Swift и Objective-C.
# Минусы
## Минусы
- CocoaPods - это сторонний инструмент и он требует дополнительной и не всегда простой установки
- Вероятность несовместимости: не все библиотеки могут быть совместимы с вашим проектом, что может привести к ошибкам.
@@ -31,13 +48,13 @@ Podfile создается всего один раз для проекта, т
Однако недостатки Cocoapods можно отнести к любой системе контроля версий. Просто системы по разному с ними справляются.
Уже хочется попробовать Cocoapods в деле? Чтож, нам тоже. Однако прежде чем его использовать, его необходимо установить.
Уже хочется попробовать Cocoapods в деле? Что ж, нам тоже. Однако прежде чем его использовать, его необходимо установить.
# Установка Cocoapods
## Установка Cocoapods
Для установки Cocoapods есть два основных способа: С помошью пакетного менеджера языка Ruby под названием Ruby Gems и с помощью пакетного менеджера для терминала под названием Homebrew. Разберем каждый из них
Для установки Cocoapods есть два основных способа: С помощью пакетного менеджера языка Ruby под названием Ruby Gems и с помощью пакетного менеджера для терминала под названием Homebrew. Разберем каждый из них
# Ruby Gems
## Ruby Gems
Ruby - это объектно-ориентированный язык программирования, используемый для написания скриптов, приложений и веб-сайтов. Исторически он был одним из основных языков для написания скриптов для macOS. Но в новых версиях macOS Ruby больше не поставляется по умолчанию, что ставит под вопрос его будущее в экосистеме Apple. Не так давно было время когда Ruby был на пике своей популярности, но сейчас он в основном используется в CI или каких-то системных скриптах.
@@ -45,9 +62,9 @@ Ruby Gem - это менеджер пакетов для языка програ
Cocoapods написан на Ruby, поэтому для его установки нужно использовать менеджер пакетов Ruby - gem. Когда вы устанавливаете Cocoapods через gem, gem загружает последнюю версию Cocoapods из `RubyGems.org` и устанавливает ее на ваш компьютер.
Чтобы установить gem, вы можете использовать встроенный менеджер пакетов Ruby, который устанавливается по умолчанию на macOS. Чтобы проверить, установлен ли gem на вашем компьютере, выполните команду `gem -v`. Если вы получили версию gem, значит он установлен.
Чтобы установить gem, вы можете использовать встроенный менеджер пакетов Ruby, который устанавливается по умолчанию на macOS. Чтобы проверить, установлен ли gem на вашем компьютере, выполните команду `gem -v`. Если вы получили версию gem, значит он установлен.
# Что делать, если gem не установлен
## Что делать, если gem не установлен
Если по каким либо причинам его нет, то вот небольшая инструкция:
@@ -58,18 +75,19 @@ Cocoapods написан на Ruby, поэтому для его установ
5. Установите нужную версию Ruby, например, `rvm install 2.7.3`
6. Установите gem, выполнив команду `gem update --system`
# Продолжение установки с помощью gem
## Продолжение установки с помощью gem
И так, у вас на компьютере есть gem. Для установки cocoapods, вам понадобится лишь одна команда:
И так, у вас на компьютере есть gem. Для установки Cocoapods, вам понадобится лишь одна команда:
`sudo gem install cocoapods`
`sudo gem install Cocoapods`
Давайте немного разберем эту команду:
- `sudo`(сокр. от англ. «Super user do»)это команда, которая сообщает терминалу что следующую команду нужно выполнить от имени администратора.
- `gem install` вызывает утилиту `gem` и передает ей команду `install`, то есть вызывает команду установки
- `cocoapods` это название того, что мы хотим установить через `gem`
После этого система запросит у вас пароль администратора и всё. У вас установлен cocoapods.
- `sudo`(сокр. от англ. «Super user do»)это команда, которая сообщает терминалу что следующую команду нужно выполнить от имени администратора.
- `gem install` вызывает утилиту `gem` и передает ей команду `install`, то есть вызывает команду установки
- `Cocoapods` это название того, что мы хотим установить через `gem`
После этого система запросит у вас пароль администратора и всё. У вас установлен Cocoapods.
Но несмотря на простоту, у установки через `gem` есть недостаток:
@@ -77,13 +95,13 @@ Cocoapods написан на Ruby, поэтому для его установ
Давайте рассмотрим другой вариант установки Cocoapods
# Homebrew
## Homebrew
Homebrew - это менеджер пакетов для macOS, который позволяет легко устанавливать и управлять пакетами и зависимостями на вашем компьютере. Он позволяет установить множество пакетов, которые не поставляются с macOS, и обновлять их легко и безопасно.
С помощью Homebrew вы можете установить пакеты, такие как Git, Ruby, Python, Node.js, PHP и многие другие. Homebrew также предоставляет утилиты для управления установленными пакетами.
Одним из преимуществ Homebrew является то, что он предоставляет отдельную версию Ruby, которая могжет использоваться вместо версий, поставляемых с macOS. Это позволяет разработчикам легко управлять зависимостями и версиями, используемыми для различных проектов.
Одним из преимуществ Homebrew является то, что он предоставляет отдельную версию Ruby, которая может использоваться вместо версий, поставляемых с macOS. Это позволяет разработчикам легко управлять зависимостями и версиями, используемыми для различных проектов.
В целом, Homebrew является мощным и гибким инструментом для установки и управления пакетами и зависимостями на macOS.
@@ -100,10 +118,11 @@ Homebrew - это менеджер пакетов для macOS, который
Готово. Теперь у вас есть cocoapods. Давайте немного разберем что же мы с вами сделали.
**Диалог**
- В чем отличие установки Cocoapods через gem и через brew?
- Установка через gem проще и быстрее, так как не требует установки Homebrew. Однако установка через brew обеспечивает более актуальную версию Cocoapods и более гибкое управление зависимостями.
# Cocopods в проекте
## Cocoapods в проекте
Давайте теперь вернемся к проекту. Что нужно, чтобы установить AppMetrica через Cocoapods в проект EmojiMixer? Давайте перечислим шаги, а затем разберем их:
@@ -118,7 +137,7 @@ Homebrew - это менеджер пакетов для macOS, который
Команда `cd` выполняет переход к папке терминале. Теперь, все следующие команды будут выполняться как бы из неё.
Теперь давайте создадим `Podfile`. Но вместо того, чтобы создавать его самому, давайте воспользуемся командой `pod init`. Эта команда создает `Podfile` по шаблону. Нам лишь нужно будет дописать в него свои зависимости.
Теперь давайте создадим `Podfile`. Но вместо того, чтобы создавать его самому, давайте воспользуемся командой `pod init`. Эта команда создает `Podfile` по шаблону. Нам лишь нужно будет дописать в него свои зависимости.
После выполнения `pod init` в папке проекта у вас появится `Podfile`. Откройте его в любом текстовом редакторе. Вы увидите что-то такую структуру:
@@ -147,7 +166,7 @@ end
# platform :ios, '9.0'
```
Здесь вам предлагается раскоментировать вторую строку, если вы хотите задать минимальную версию для подов. Это может быть полезно, так как если какая-либо библиотека совместима с конкретной версией платформы, то `cocoapods` сообщит вам об этом заранее.
Здесь вам предлагается раскомментировать вторую строку, если вы хотите задать минимальную версию для подов. Это может быть полезно, так как если какая-либо библиотека совместима с конкретной версией платформы, то `Cocoapods` сообщит вам об этом заранее.
```sh
target 'EmojiMixer' do
@@ -162,7 +181,7 @@ end
use_frameworks!
```
Здесь вам предлагается закоментировать следующую строку, если вы не используете динамические фреймворки. Мы не будем вдавать в подробности того, что это такое. Скажем лишь, что можно оставить флаг.
Здесь вам предлагается закомментировать следующую строку, если вы не используете динамические фреймворки. Мы не будем вдаваться в подробности того, что это такое. Скажем лишь, что можно оставить флаг.
```sh
# Pods for EmojiMixer
@@ -179,20 +198,13 @@ target 'EmojiMixerTests' do
Так как у нас есть таргет для тестирования, то `pod` предусмотрел секцию и для него. Здесь вы можете устанавливать зависимости исключительно для `EmojiMixerTests`. Зачем это нужно? Ну например, если бы вы устанавливали библиотеку для скриншот-тестирования, то вам она нужно только в тестовом таргете, а не во всем приложении.
Теперь давайте добавим зависимости. Нам нужно добавить AppMetrica. Давайте посмотрим в документации как назывался под **Ссылка: https://appmetrica.yandex.ru/docs/mobile-sdk-dg/ios/ios-quickstart.html**:
Теперь давайте добавим зависимости. Нам нужно добавить AppMetrica. Давайте посмотрим в документации как назывался под **Ссылка: https://appmetrica.yandex.ru/docs/ru/sdk/ios/analytics/quick-start**:
`pod 'YandexMobileMetrica/Dynamic', '4.5.0'`
`pod 'AppMetricaAnalytics', '~> 5.11.0'`
Мы выбрали динамическую версию библиотеки исходя из рекомендации разработчиков:
Обратите внимание, что мы указали примерную версию библиотеки которую нужно установить. Дело в том, что в ряде случаев обновления библиотек могут сломать ваш проект. Поэтому обновление библиотеки это далеко не всегда радостный и приятный момент. Если вы уберете '5.11.0', то `Cocoapods` всегда будет загружать самую последнюю версию на момент запуска команды `pod install`. Здесь оператор `~>` указывает, что будет установлена версия 5.11.0 или любая более новая патч-версия (например, 5.11.1), но не версия 5.12.0 и выше.
```
Примечание. Если в Podfile присутствует строка use_frameworks!, рекомендуем использовать динамический фреймворк.
```
Обратите внимание, что мы четко указали какую именно версию библиотеки нужно установить. Дело в том, что в ряде случаев обновления библиотек могут сломать ваш проект. Поэтому обновление библиотеки это далеко не всегда радостный и приятный момент. Если вы уберете '4.5.0', то `cocoapods` всегда будет загружать самую последнюю версию на момент запуска команды `pod install`.
Теперь снова откройте терминал. Если вы его закрыли то снова перейдите в папку проекта командой
`cd <Путь до папки>/EmojiMixer-step-by-step`. Если вы уже в ней, то просто введите `pod install`.
Теперь снова откройте терминал. Если вы его закрыли то снова перейдите в папку проекта командой `cd <Путь до папки>/EmojiMixer-step-by-step`. Если вы уже в ней, то просто введите `pod install`.
Вы увидите в терминале ход выполнения установки подов:
@@ -200,15 +212,16 @@ target 'EmojiMixerTests' do
❯ pod install
Analyzing dependencies
Downloading dependencies
Installing YandexMobileMetrica (4.5.0)
Installing AppMetrica...
...
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `EmojiMixer.xcworkspace` for this project from now on.
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
Pod installation complete! There is 1 dependency from the Podfile and 22 total pods installed.
```
Команда сообщает вам о том, что `EmojiMixer.xcworkspace` был впервый создан и теперь надо использовать его. И что был загружен под `YandexMobileMetrica`. Теперь если вы посмотрите на папку проекта, то заметите в ней изменения:
Команда сообщает вам о том, что `EmojiMixer.xcworkspace` был создан и теперь надо использовать его. И что был загружен под `AppMetricaAnalytics`. Теперь если вы посмотрите на папку проекта, то заметите в ней изменения:
![Changes in folder](./images/1.png)
@@ -218,17 +231,17 @@ Pod installation complete! There is 1 dependency from the Podfile and 1 total po
Разберем по порядку
# Podfile.lock
## Podfile.lock
Когда вы грузите зависимости командой `pod install`, то `cocoapods` нужно знать какая версия уже загружена, чтобы не грузить её дважды. Вот для этого и нужен `Podfile.lock`. Он хранит все загруженные версии всех подов. Важно помнить, что у подов который вы добавляете в свой проект так же могут быть зависимости. Их список и версии то же хранятся в `Podfile.lock`.
Когда вы грузите зависимости командой `pod install`, то `Cocoapods` нужно знать какая версия уже загружена, чтобы не грузить её дважды. Вот для этого и нужен `Podfile.lock`. Он хранит все загруженные версии всех подов. Важно помнить, что у подов который вы добавляете в свой проект так же могут быть зависимости. Их список и версии то же хранятся в `Podfile.lock`.
Если вы откроете этот файл, то увидите что были загружены дополнительные библиотеки, необходимые для `YandexMobileMetrica/Dynamic`
Если вы откроете этот файл, то увидите что были загружены дополнительные библиотеки, необходимые для `AppMetricaAnalytics`
# Папка Pods
## Папка Pods
В неё грузятся все зависимости для данного проекта. При чем не только те, что указаны напрямую в `Podfile`, но и те что загружены как зависимости для них.
# Файл `xcworkspace`
## Файл `xcworkspace`
`xcworkspace` это файл Xcode, который позволяет вам объединить несколько проектов в одном рабочем пространстве. Например, до этого у вас был только один проект `EmojiMixer.xcodeproj`. Теперь, появился ещё один `Pods.xcodeproj`. Почему поды добавлены в отдельный проект? Чтобы максимально отделиться от основного проекта приложения. Таким образом любые изменения в проекте подов не повлияют на ваш проект и не сломают код. Это важно.
@@ -236,17 +249,18 @@ Pod installation complete! There is 1 dependency from the Podfile and 1 total po
Для знакомства с ним, откройте этот файл. Главное отличие вы можете видеть в колонке слева:
![](./images/2.png)
![xcworkspace](./images/2.png)
Тут вы видите и ваш основной проект и проект подов. Всю работу вы конечно же будете делать в проекте основном проекте. Код в проекте подов не рекомендуем трогать никогда. Так как эти изменения меняют только вашу версию этой библиотеки и ни у кого её нет. Кроме того, следующий вызов `pod install` сбросит все ваши изменения.
Работа с `xcworkspace` ничем не отличается. Просто вам теперь нужно будет открывать `EmojiMixer.xcworkspace` вместо `EmojiMixer.xcodeproj`, иначе проект не скомпилируется. Ведь ему не известно ни о каких подах
# Добавление подов в `.gitignore`
## Добавление подов в `.gitignore`
Включение в проект пода `YandexMobileMetrica` изменило его конфигурацию и добавило в папку файлы. Если вы используете Git для контроля версий проекта, он автоматически добавил их в свой репозиторий и начал отслеживать изменения.
Включение в проект пода `AppMetricaAnalytics` изменило его конфигурацию и добавило в папку файлы. Если вы используете Git для контроля версий проекта, он автоматически добавил их в свой репозиторий и начал отслеживать изменения.
Это ненужное нововведение, потому что:
- Вам не требуется менять код в проекте подов.
- Если надо — вы всегда сможете загрузить поды в проект повторно.
- Сохранение подов в репозитории Git увеличивает его объём.
@@ -260,11 +274,12 @@ Pod installation complete! There is 1 dependency from the Podfile and 1 total po
> Файлы `Podfile` и `Podfile.lock`, в которых хранится конфигурация подов, должны всегда сохраняться в Git. Никогда не добавляйте их в `.gitignore`.
# Подведём итоги
## Подведём итоги
Cocoapods — всё ещё востребованный инструмент, которым важно уметь пользоваться. Для установки используйте `gem` или `Homebrew` — лучше последний вариант: он более гибкий в плане версии подов.
Для установки зависимостей выполните три шага:
1. Инициализируйте Podfile командой `pod init`.
2. Добавьте зависимости в Podfile.
3. Установите зависимости командой `pod install`.
@@ -1,27 +1,34 @@
Теперь, когда вы узнали о том, как работает AppMetrica, давайте итегрируем SDK этого инструмента в наш проект `EmojiMixer`. Для этого сначала обратимся к официально [документации по интеграции](https://appmetrica.yandex.ru/docs/mobile-sdk-dg/ios/ios-quickstart.html).
# Интегрируем Яндекс Метрику
Теперь, когда вы узнали о том, как работает AppMetrica, давайте интегрируем SDK этого инструмента в наш проект `EmojiMixer`. Для этого сначала обратимся к официально [документации по интеграции](https://appmetrica.yandex.ru/docs/ru/sdk/ios/analytics/quick-start).
В первую очередь подключим сам SDK. Чтобы подключить AppMetrica в iOS-приложение, необходимо выполнить следующие шаги:
1. Зарегистрировать приложение в AppMetrica и получить API-ключ. Для этого нужно создать новый аккаунт на сайте AppMetrica и зарегистрировать новое приложение. Этот пункт мы уже выполнили в предыдущем уроке.
1. Зарегистрировать приложение в AppMetrica и получить API-ключ. Для этого нужно создать новый аккаунт на сайте AppMetrica и зарегистрировать новое приложение. Этот пункт мы уже выполнили в предыдущем уроке.
2. Добавить библиотеку AppMetrica в проект. Для этого мы будем использовать CocoaPods (что такое CocoaPods и как с ним работать, мы рассказывали в предыдущей теме). Добавьте строку `pod 'YandexMobileMetrica` в Podfile, а затем выполните команду `pod install` в терминале.
2. Добавить библиотеку AppMetrica в проект:
Для этого можно использовать Swift Package Manager (SPM) или CocoaPods.
- **SPM (рекомендуемый способ):** В Xcode выберите File > Add Packages..., введите URL репозитория AppMetrica (`https://github.com/appmetrica/appmetrica-sdk-ios`) и добавьте пакет `AppMetricaCore`.
- **CocoaPods:** Если вы предпочитаете использовать CocoaPods *(что такое CocoaPods и как с ним работать, мы рассказывали в предыдущем уроке)*, добавьте строку `pod 'AppMetricaAnalytics'` в ваш Podfile, а затем выполните команду `pod install` в терминале.
В этом уроке мы продолжим использовать CocoaPods, как было описано ранее, но вы можете выбрать SPM для вашего проекта.
3. Инициализировать AppMetrica в `AppDelegate.swift` вашего приложения. Для этого нужно добавить следующий код в метод `application(_:didFinishLaunchingWithOptions:)` следующий код:
```swift
import YandexMobileMetrica
import AppMetricaCore
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
guard let configuration = YMMYandexMetricaConfiguration(apiKey: "API_KEY") else { // используйте ваш ключ
return true
if let configuration = AppMetricaConfiguration(apiKey: "Your_API_Key") { // используйте ваш ключ
AppMetrica.activate(with: configuration)
}
YMMYandexMetrica.activate(with: configuration)
return true
}
```
> Подставьте ваш API KEY, который вы получили при создании приложения в прошлом уроке. Также не забудьте импортировать саму библиотеку — `import YandexMobileMetrica`.
> Подставьте ваш API KEY, который вы получили при создании приложения в прошлом уроке. Также не забудьте импортировать саму библиотеку — `import AppMetricaCore`.
Кнопка
Далее
@@ -33,24 +40,24 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau
Конечно, эти данные необходимы, но их недостаточно для того, чтобы понять, как конкретно пользователи используют приложение. Поэтому нам нужно добавить возможность отправлять собственные события.
# Отправка собственных событий
## Отправка собственных событий
В официальной [документации по интеграции](https://appmetrica.yandex.ru/docs/data-collection/events-ios.html) говорится о возможности отправки собственных событий. Что это значит?
В официальной [документации по интеграции](https://appmetrica.yandex.ru/docs/ru/sdk/ios/analytics/ios-operations#report-event) говорится о возможности отправки собственных событий. Что это значит?
Когда пользователь или приложение совершает какое-то действие, мы можем отправить какое-то событие. Например, каждый раз, когда пользователь:
- нажимает кнопку «+» в `EmojiMixer`,
- пытается проскроллить экран,
- нажимают кнопку «Удалить всё»,
- нажимает кнопку «+» в `EmojiMixer`,
- пытается проскролить экран,
- нажимает кнопку «Удалить всё»,
мы можем оповестить об этом систему аналитики. Обладая информацией о таких событиях, нам гораздо проще составить картину того, как пользователи на самом деле используют приложение.
мы можем оповестить об этом систему аналитики. Обладая информацией о таких событиях, нам гораздо проще составить картину того, как пользователи на самом деле используют приложение.
> Обычно описание таких событий, а также список данных для каждого из них, предоставляет аналитик или продакт-менеджер. Именно они знают, что нужно, чтобы понять, как работает приложение. Но иногда и сами разработчики добавляют какие-то события и данные, чтобы потом на их основании сделать выводы насчёт того, насколько корректно ведёт себя приложение.
> Например, если вы обнаружите, что в аналитике нет данных о том, что кто-то нажимает кнопку «+», то скорее всего это значит, что пользователи просто не могут её нажать — а это может быть сигналом о том, что в вашем коде есть баг.
Также с каждым событием мы можем отправлять какие-то данные. В принципе, они могут быть любыми, но при этом они должны как-то относиться к произошедшему событию. Например, когда пользователь нажимает кнопку «Удалить всё», мы можем добавить к событию количество миксов, которые пользователь решил удалить.
# Самостоятельная задача
## Самостоятельная задача
А теперь давайте попробуем добавить два события в `EmojiMixer`:
@@ -62,27 +69,27 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions lau
```swift
let params : [AnyHashable : Any] = ["key1": "value1", "key2": "value2"]
YMMYandexMetrica.reportEvent("EVENT", parameters: params, onFailure: { error in
AppMetrica.reportEvent(name: "EVENT", parameters: params, onFailure: { error in
print("REPORT ERROR: %@", error.localizedDescription)
})
```
Также не забудьте импортировать саму библиотеку в тех местах, где вы её используете — `import YandexMobileMetrica`. Попробуйте интегрировать отправку этих событий в код приложения `EmojiMixer`.
Также не забудьте импортировать саму библиотеку в тех местах, где вы её используете — `import AppMetricaCore`. Попробуйте интегрировать отправку этих событий в код приложения `EmojiMixer`.
> Заметка о правильном тоне интеграции сторонних библиотек.
> В случае с интеграцией сторонних библиотек работает тот же самый принцип, что вы применяли к CoreData в предыдущем спринте: их необходимо абстрагировать. > То есть сделать так, чтобы код самой библиотеки присутствовал только в одном месте, а приложение взаимодействовало с ним через обёртку — например, через сервис `AnalyticsService`. В таком случае, во-первых, вы легко сможете написать Unit-test'ы, передав mock-объект вместо реального сервиса. Во-вторых, если вы захотите сменить свой инструмент аналитики, вам надо будет изменить код только внутри этого сервиса.
> В случае с интеграцией сторонних библиотек работает тот же самый принцип, что вы применяли к CoreData в предыдущем спринте: их необходимо абстрагировать. > То есть сделать так, чтобы код самой библиотеки присутствовал только в одном месте, а приложение взаимодействовало с ним через обёртку — например, через сервис `AnalyticsService`. В таком случае, во-первых, вы легко сможете написать Unit-test'ы, передав mock-объект вместо реального сервиса. Во-вторых, если вы захотите сменить свой инструмент аналитики, вам надо будет изменить код только внутри этого сервиса.
Ссылка на авторское решение - [ссылка](ссылка на авторское решение)
# Тестирование
## Тестирование
После того как вы интегрируете эти события, попробуйте протестировать ваше приложение: открывайте его, закрывайте, нажимайте на кнопки. После этого подождите несколько минут и откройте отчёты AppMetrica. Там должны появиться первые данные:
![image](./images/part-3/report.png)
> Обратите внимание, что в реальной работе аналитика очень плохо поддаётся ручному тестированию. Единственно правильный способ тестирования — это написание тестов. «Вручную» у вас вряд ли получится убедиться, что все события доходят до системы аналитики, поскольку эти системы крайне сложно устроены, рассчитаны на большой поток данных. Также они ориентированы на показ общей статистики, поэтому не всегда сразу показывают данные в режиме реального времени.
> Обратите внимание, что в реальной работе аналитика очень плохо поддаётся ручному тестированию. Единственно правильный способ тестирования — это написание тестов. «Вручную» у вас вряд ли получится убедиться, что все события доходят до системы аналитики, поскольку эти системы крайне сложно устроены, рассчитаны на большой поток данных. Также они ориентированы на показ общей статистики, поэтому не всегда сразу показывают данные в режиме реального времени.
# Подведём итоги
## Подведём итоги
Мы с вами сделали первые шаги в такой большой теме, как аналитика:
@@ -1,11 +1,13 @@
# Задание для самостоятельной работы
Вы завершили 17 спринт и проверили знания — поработали над проектом `EmojiMixer`. Теперь пора взяться за задачи по проекту `Tracker` — дополнить его важными элементами. Так вы закрепите на практике теорию и навыки, которые получили на курсе.
Вам нужно сдать проект, в котором:
- реализовано контекстное меню для треков на главном экране,
- есть скриншот-тесты для главного экрана,
- реализована тёмная тема для главного экрана,
- подключена `AppMetrica` с помощью CocoaPods и присылаются события для действий на главном экране,
- подключена `AppMetrica` (любым удобным способом),
- присылаются события для действий на главном экране,
- реализован экран статистики,
- есть английская локализация на главном экране,
- проведено код-ревью в группах.
@@ -14,60 +16,55 @@
> Не забывайте обращаться к наставникам, если возникнут вопросы. Всё получится!
# Порядок сдачи домашнего задания
## Порядок сдачи домашнего задания
1. Выполните задачу в Xcode.
2. После проверки по чек-листу загрузите готовую задачу в ваш проект на GitHub, в отдельную ветку с названием **sprint_17**. Проект должен быть **открытым**.
3. Создайте Pull Request и скопируйте ссылку на него. Вставьте её в специальную форму на сайте Практикума через кнопку «Сдать работу».
# Контекстное меню
### Контекстное меню
Убедитесь, что:
Макет контекстного меню для ячейки трекера вы найдёте на отдельном листе в фигме. Реализуйте его на главном экране.
Функциональность контекстного меню:
1. При долгом нажатии на ячейку отображается контекстное меню.
![](./img/3.png)
![Контекстное меню](./img/3.png)
2. В контекстном меню три пункта.
Если привычка закреплена, первый пункт меню — «Открепить».
![](./img/4.png)
Если привычка не закреплена — «Закрепить».
![](./img/3.png)
По нажатии на пункт должно идти закрепление или открепление привычки на главном экране.
Второй пункт меню — «Редактировать». По нажатии запускается флоу редактирования привычки.
Третий пункт меню — «Удалить». По нажатии запускается флоу удаления привычки.
**Первый пункт меню** - «Закрепить/Открепить». Обратите внимание, первый пункт контекстного меню является дополнительной задачей, со звёздочкой. Она не влияет на оценку. Но если вы её выполните, то получите дополнительный опыт и знания. Описание задачи закрепления привычки вы найдёте ниже, в разделе «Задания со звёздочкой». Если вы решите не реализовывать эту задачу, то уберите первый пункт из контекстного меню и в нём останется только два пункта описанных ниже.
**Второй пункт меню** — «Редактировать». По нажатии запускается флоу редактирования привычки.
**Третий пункт меню** — «Удалить». По нажатии запускается флоу удаления привычки.
3. Пункт удаления выделен красным цветом.
За отображение контекстного меню отвечает метод делегата коллекции `UICollectionViewDelegate`. Если нужно освежить знания, вернитесь к [уроку «Дополнительные возможности»](Ссылка: Спринт 14, тема 2, урок 4 Дополнительные возможности**).
# Фильтры
## Фильтры
Вот что должно у вас получиться:
![](./img/6.png) ![](./img/7.png)
![Фильтры](./img/6.png) ![Фильтры](./img/7.png)
Для этого убедитесь, что:
1. На главном экране добавлена кнопка «Фильтры».
Она не должна перекрывать трекеры, которые отображаются, и мешать с ними взаимодействовать. При необходимости реализуйте возможность оверскролла, чтобы ячейки с трекерами прокручивались немного выше кнопки «Фильтры».
2. По нажатии на кнопку «Фильтры» модально появляется окно со списком из четырёх вариантов фильтрации. Выберите один для фильтрации трекеров на главном экране в соответствии с выбором. Если какой-то вариант фильтрации уже был выбран, при открытии списка фильтров он должен быть отмечен синей галочкой. Если ранее фильтры не выбирались, считаем, что был выбран первый вариант — «Все трекеры».
- Все трекеры. Отображаются все трекеры на выбранный в календаре день и при переключении дней.
- Трекеры на сегодня. В календаре автоматически устанавливается текущая дата, показаны все трекеры на день. При переключении дней отображаются все трекеры.
2. По нажатии на кнопку «Фильтры» модально появляется окно со списком из четырёх вариантов фильтрации. Выберите один для фильтрации трекеров на главном экране в соответствии с выбором. Если какой-то вариант фильтрации уже был выбран, при открытии списка фильтров он должен быть отмечен синей галочкой, кроме варианта «Все трекеры». Если ранее фильтры не выбирались, считаем, что был выбран первый вариант — «Все трекеры».
- Все трекеры. Отображаются все трекеры на любой выбранный в календаре день и при переключении дней. Это сброс фильтрации до стандартного состояния.
- Трекеры на сегодня. В календаре автоматически устанавливается текущая дата, показаны все трекеры на день. При переключении дней отображаются все трекеры. Это тоже сброс фильтрации до стандартного состояния, но с дополнительным переключением на текущую дату.
- Завершённые. Пользователь увидит только выполненные трекеры или привычки на выбранный день. При переключении дней отображаются только завершённые трекеры.
- Незавершённые. Будут отображены только невыполненные трекеры на выбранный день. При переключении дней отображаются только незавершённые трекеры.
Дополнительные требования:
- Все фильтры зависят от выбранной даты.
- Если нет трекеров на выбранный день, кнопка фильтрации должна быть скрыта.
- Текущий фильтр должен быть отмечен синей галочкой.
- При переключении в календаре дней действие фильра **не** отменяется.
- Текущий фильтр должен быть отмечен синей галочкой. Кроме варианта «Все трекеры» и «Трекеры на сегодня» - их выделять галочкой в списке фильтров не нужно, так как это сброс фильтрации до стандартного состояния, а не установка нового фильтра.
- При переключении в календаре дней действие фильтра **не** отменяется.
- После выбора фильтра экран фильтров автоматически закрывается, отфильтрованные трекеры отображаются на экране.
- Если по фильтру ничего не найдено, пользователь увидит специальную заглушку — «Ничего не найдено».
По желанию можно добавить дополнительный визуальный сигнал, чтобы показать: фильтр активен. Например, сменить цвет текста на кнопке «Фильтры». Белый цвет будет значить, что видно все трекеры; красный — что фильтр активен и видно не все трекеры. Это напомнит пользователю, что у него включены фильтры.
Подсказки
---> НАЧАЛО СКРЫВАШКИ
Ими пользоваться необязательно: возможны и другие варианты реализации.
По желанию можно добавить дополнительный визуальный сигнал, чтобы показать: фильтр активен. Например, сменить цвет текста на кнопке «Фильтры». Белый цвет будет значить, что видно все трекеры; красный — что фильтр активен и видно не все трекеры. Это напомнит пользователю, что у него включены фильтры. Установка фильтров «Все трекеры» и «Трекеры на сегодня» сбрасывает фильтрацию до стандартного состояния, поэтому визуальный сигнал нужно переключить в состояние «фильтр **не** активен».
1. «Модально» — это поверх главного окна с помощью метода `present(_:animated:completion:)`.
2. «Все трекеры» и «Трекеры на сегодня» отличаются только автоматическим переключением текущей даты на сегодняшний день.
@@ -78,16 +75,14 @@
- `UserDefaults`,
- `CoreData`;
Для случая перезапуска приложения можно не сохранять выбранный фильтр (но он должен сохраняться на время работы приложения).
5. Для настройки оверскролла может быть несколько подходов:
5. Для настройки оверскролла может быть несколько подходов:
- использование `alwaysBounceVertical` для подпрыгивания,
- регулировка `contentOffset` для более тонкого контроля над скроллом,
- добавление дополнительного пространства, внедрения дополнительных секций или ячеек в начале или конце UICollectionView,
- временное скрытие кнопки «Фильтры» в конце списка трекеров.
6. Заглушка «Ничего не найдено» может быть такой же, как при поиске.
<--- КОНЕЦ СКРЫВАШКИ
# Скриншот-тесты
## Скриншот-тесты
Убедитесь, что:
@@ -101,9 +96,9 @@
Если тест провалился — вы сделали всё верно.
# Тёмная тема
## Тёмная тема
Добавьте в проект тёмную тему по дизайну.
Добавьте в проект тёмную тему по дизайну.
Убедитесь, что:
@@ -119,11 +114,11 @@
После добавления тёмной темы запустите скриншот-тесты для светлой. Тесты должны проходить.
# Аналитика
## Аналитика
Убедитесь, что:
1. В проекте подключена библиотека `AppMetrica` через менеджер CocoaPods.
1. В проекте подключена библиотека `AppMetrica`. Рекомендуется использовать Swift Package Manager (SPM) для подключения. *(Если вы используете CocoaPods, убедитесь, что он настроен корректно)*
2. Действия на главной отправляют:
- открытие,
- закрытие,
@@ -135,7 +130,7 @@
В каждом событии должны быть поля:
```
```text
event
screen
item
@@ -144,23 +139,23 @@ item
Вот какая информация должна в них передаваться:
- event:
- событие открытия экрана: значение `open`,
- событие закрытия экрана: `close`,
- событие тапа на кнопку: `click`.
- событие открытия экрана: значение `open`,
- событие закрытия экрана: `close`,
- событие тапа на кнопку: `click`.
- screen:
- название экрана, на котором произошло событие. Главный экран: `Main`.
- название экрана, на котором произошло событие. Главный экран: `Main`.
- item:
- не отправляется для событий `open` и `close`,
- для событий тапа на кнопку имеет значения:
- `add_track` для кнопки добавления нового трека,
- `track` — тапа на кнопку о выполнении трека,
- `filter` — тапа на кнопку фильтров,
- `edit` — тапа на кнопку «Редактировать» в контекстном меню,
- `delete` — тапа на кнопку «Удалить» в контекстном меню.
- не отправляется для событий `open` и `close`,
- для событий тапа на кнопку имеет значения:
- `add_track` для кнопки добавления нового трека,
- `track` — тапа на кнопку о выполнении трека,
- `filter` — тапа на кнопку фильтров,
- `edit` — тапа на кнопку «Редактировать» в контекстном меню,
- `delete` — тапа на кнопку «Удалить» в контекстном меню.
На тестах рекомендуем дублировать в логи события, которые вы отправляете.
# Экран статистики
## Экран статистики
Убедитесь, что:
@@ -169,14 +164,14 @@ item
- Экран соответствует [макету](https://www.figma.com/design/TjqEozMu6WUwtWMB08RZSu/Tracker?node-id=1-11415&t=AHdHNZ8n9Pz3L79d-11).
- Реализован кейс для пустого экрана статистики; он описан в макетах.
![Statistics_уьзен](./img/2.png)
![Statistics_empty](./img/2.png)
Детали реализации остаются на ваше усмотрение. Если возникнут трудности, воспользуйтесь советами:
- Счётчик статистики пересчитывайте при каждом действии пользователя с треком.
- Хранить статистику можно в `CoreData` или `UserDefaults`.
# Локализация
## Локализация
Убедитесь, что:
@@ -189,18 +184,32 @@ item
Менять названия трекеров и категории не нужно.
# Код-ревью
## Код-ревью
Напомним, вам нужно провести код-ревью `Экрана статистики` внутри своих команд. Не проверяйте код всех участников команды: выберите напарника или напарницу и обменяйтесь с ними ссылками на Pull Request в GitHub. Оставьте комментарии.
1. Оцените качество кода: понятно ли он читается, отвечает ли стандартам Swift?
2. Посмотрите на производительность. Хороший код не блокирует UI-поток, не приводит к утечкам памяти или неприятным фризам (**Глоссарий** От англ. to freeze — «замерзать»; в контексте разработки означает замедление или зависание приложения, когда оно перестаёт отвечать на действия пользователя), не снижает производительность устройства.
2. Посмотрите на производительность. Хороший код не блокирует UI-поток, не приводит к утечкам памяти или неприятным фризам (**Глоссарий** От англ. to freeze — «замерзать»; в контексте разработки означает замедление или зависание приложения, когда оно перестаёт отвечать на действия пользователя), не снижает производительность устройства.
3. Следите за надёжностью. Код не должен приводить к сбоям, потерям данных или другим проблемам, которые могут повлиять на работу приложения. С подозрением относитесь к force-операциям и пропущенным блокам в условных операторах.
4. Используйте лучшие практики. Если в коде есть дополнительные тесты, покрывающие новую функциональность, а вся необходимая документация к коду написана в виде [doc-комментариев](https://developer.apple.com/documentation/xcode/writing-symbol-documentation-in-your-source-files){target="\_blank"} — это большой плюс.
# Задачи со звёздочкой
## Задачи со звёздочкой
Если вы хотите поработать больше, можете добавить:
Задания из этого раздела не обязательны и не повлияют на вашу оценку. Но если вы хотите поработать ещё больше и глубже разобраться в возможностях UIKit, можете добавить:
### Закрепление привычки
Реализуйте закрепление привычки - первый пункт в контекстном меню. Если привычка закреплена, то она отображается в специальной категории (секции) «Закреплённые». Если не закреплена - то на своём месте, в исходной категории. При выборе пункта «Закрепить/Открепить» у трекера появляется или исчезает значок закрепления в правом верхнем углу.
Если привычка закреплена, первый пункт меню — «Открепить».
![Контекстное меню](./img/4.png)
Если привычка не закреплена — «Закрепить».
![Контекстное меню](./img/3.png)
По нажатии на первый пункт контекстного меню должно происходит закрепление или открепление привычки на главном экране. А именно, привычка должна перемещаться в категорию «Закреплённые» или из неё удаляться. При этом, если есть закреплённые привычки, то они должны отображаться вверху списка трекеров в специальной категории (секции) «Закреплённые». Если привычки не закреплены - то они отображаются на своём месте, в исходной категории. Если закреплённых трекеров нет, то категория «Закреплённые» не отображается. Обратите внимание что категория «Закреплённые» должна быть видна только в том случае, если есть закреплённые трекеры. Если нет закреплённых трекеров, то категория не отображается. А так же категория «Закреплённые» **не** должна быть видна в списке категорий на экране выбора категории при создании нового трекера.
### Дополнительные задачи со звёздочкой
1. Скриншот-тесты для остальных экранов.
2. События аналитики на остальные экраны. Важно, чтобы структура событий следовала схеме для главного экрана (смотрите пункт «Аналитика»).