reactive swift с чего начать

RxSwift в действии — пишем реактивное приложение

Если верить последним тенденциям, то FRP набирает обороты и не собирается останавливаться. Не так давно я столкнулся с проектом, посвященным FRP — ReactiveX, и его реализацией для Swift — RxSwift. На Хабре уже была небольшая статья, которая будет полезна для начального понимания RxSwift. Я хотел бы развить эту тему, поэтому заинтересовавшимся — добро пожаловать под кат!

Лиха беда начало

И это действительно так. Самое сложное, с чем мне пришлось столкнуться — совершенно другое построение программного кода. С моим опытом императивного программирования было тяжело перестраиваться на новый лад. Но чутьё подсказывало мне, что в этом стоит разобраться; у меня ушло 2 недели паники на то, чтобы вникнуть в суть ReactiveX и я не жалею о потраченном времени. Поэтому сразу хотел бы предупредить — статья требует понимания терминов ReactiveX, таких как Observable, Subscriber и т.д.

Итак, начнем. Будем писать простую читалку своей стены с Facebook. Для этого нам понадобятся RxSwift, ObjectMapper для маппинга данных, Facebook iOS SDK и MBProgressHUD для индикации загрузки. Создаем проект в XCode, подключаем к нему вышеуказанные библиотеки (я использую CocoaPods), настраиваем связку с Facebook по инструкции и переходим к кодингу.

Экран логина

Изобретать велосипед мы не будем, просто разместим по центру экрана уже готовую кнопку от Facebook — FBSDKLoginButton:

Не забываем добавить делегата FBSDKLoginButtonDelegate для кнопки логина, а также реализовать методы делегата:

Тут все просто — если ошибка входа или пользователь нажал кнопку «Отмена» на экране авторизации Facebook, то выводим сообщение об этом в виде alert’а, а если все ок — отправляем его на следующий экран со списком новостей. Функцию логаута я не стал трогать. Как мы видим, пока все достаточно тривиально и ни о какой реактивности речи не идет. Тут тоже достаточно тонкий момент — не совать реактивность во все щели помнить про принцип KISS.

Экран новостей

Напишем функцию получения списка новостей со стены Facebook, возвращаемый тип которой будет Observable:

Что происходит в этом коде? Формируется сетевой запрос FBSDKGraphRequest на получение новостей «me/feed», после чего мы отдаем команду на выполнение запроса и отслеживаем статус в блоке completition; в случае ошибки передаем её в Observable, в случае успеха — передаем в Observable полученные данные.

Примечание: я передаю в FBSDKGraphRequest переменную с пустым набором параметров. Это нужно для того, чтобы Facebook не плакал выводил предупреждения в логах о том, что поле fields в параметрах является обязательным. В принципе, все работает и без этого параметра, но мне так спокойней спится.

Немного отойдем от процесса написания приложения и поговорим о маппинге данных. Я решаю эту задачу с помощью ObjectMapper, он позволяет это делать достаточно быстро и просто:

Предлагаю сразу написать сетевой запрос для получения детальной информации о новости:

Как мы видим, я передал в переменной parameters кучу полей — это все поля, которые были в документации. Разбирать их все я не буду, только часть. Вот маппинг данных:

Как видим, без ложки дегтя тут тоже не обошлось. Например, при разборе json-объекта «to», который содержит в себе одно поле «data», которое в свою очередь является json-массивом, мне пришлось изворачиваться следующим образом:

В принципе, я мог создать файл с одним полем «data» и спокойно размаппить объект там, но мне показалась глупой сама идея создавать новый файл ради маппинга одного поля. Если у кого-то из Вас есть более элегантное решение этой задачи — я напьюсь на радостях буду рад узнать о нем.

Вернемся к нашим баранам. С Facebook’ом мы связались, получили список новостей в виде Observable, теперь нам нужно отобразить эти данные. Для этой цели я буду использовать шаблон MVVM. Моя вольная трактовка этого шаблона с учетом использования ReactiveX звучит так: во ViewModel есть Observable, который генерирует события, а View подписывается на эти события и обрабатывает их. То есть, ViewModel не зависит от того, кто на него подписан — если подписчики есть, то Observable генерирует данные, если подписчиков нет, то Observable ничего не генерирует (это утверждение верно для «холодных» Observable, т.к. «горячие» Observable всегда генерируют данные). Напишем ViewModel для экрана новостей:

Давайте разберем код. В поле input мы передаем таблицу из View, в поле dependency — класс API и Wireframe. В классе есть 3 переменные: feedsObservable возвращает Observable со списком новостей, clickObservable является обработчиком нажатия на ячейку таблицы, а indicator это булева переменная, определяющая нужно ли выводить на экран индикатор загрузки. В коде есть сразу 2 любопытных класса — Wireframe и ViewIndicator, остановимся на них поподробней. Wireframe это не что иное, как «реактивная» реализация alert’ов. Я взял эту реализацию из примеров в репозитории RxSwift. ViewIndicator представляет собой трекинг, а функция trackView из этого класса выполняется до тех пор, пока в цепочке выполняется хотя бы одна последовательность, поэтому trackView удобно использовать для показа индикатора загрузки. Я не буду приводить код в данной статье — вы сможете найти его в репозитории проекта, ссылка находится внизу статьи.

Коснемся логики работы наших Observable. Первый — feedsObservable — получает ответ с Facebook, потом в блоке map из полученных данных извлекаются и возвращаются список новостей, потом стоит обработка ошибок, ну и trackView для отображения загрузки. Второй — clickObservable — отслеживает нажатие на ячейку таблицы, после чего вызывает сетевой запрос на получение детальной информации о новости. Супер, с моделью закончили, переходим непосредственно к View.

Я сразу приведу код View, после чего мы с Вами его разберем:

Первым делом, создаем viewModel. Далее нужно создать индикатор загрузки и как-то его связать с ViewIndicator. Для этого нам необходимо написать Extension для MBProgressHUD:

Если в MBProgressHUD подается какое-то значение, то отображаем индикатор. Если никаких значений не подается — скрываем его. Теперь нам нужно настроить биндинг между нашим MBProgressHUD и ViewIndicator. Делается это вот так:

После чего настраиваем биндинг между UITableView и получением данных, а также между нажатием на элемент UITableView и переходом на новый экран. Экран детальной информации о посте я также сделал без «реактивности»:

На этом у меня все. Исходный код проекта на Github можно скачать по этой ссылке. Если вам понравилась моя статья, то я лопну от счастья с удовольствием продолжу писать про RxSwift и постараюсь раскрыть его потенциал в более нетривиальных задачах.

Источник

RxSwift часть 1

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Доброго времени суток, хабровчане. В этом цикле статей, я бы хотел рассказать о реактивном программировании, а именно о фреймворке
RxSwift. На Хабре и в сети были статьи по RxSwift, но, на мой взгляд, они слишком трудны для начинающих. Поэтому, если вы начинаете постигать реактивное программирование в iOS, то прошу под кат.

Начнем с определения, что такое реактивное программирование.

Реактивное программирование — парадигма программирования, ориентированная на потоки данных и распространение изменений.

Так гласит нам великая википедия.

Я не буду расписывать как установить фреймворк, это легко сделать перейдя по ссылке. Давайте приступим к практике.

Observable

Начнем с простого, но важного, наблюдаемый объект или Observable. Observable это то, что будет отдавать нам данные, нужен он для генерации потока данных.

BINGO! Мы создали первый observable.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Так как мы создали наблюдаемый объект, то логично, что нам необходимо создать объект, который будет наблюдать.

в лог мы получаем следующее:

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Observable отправляет нам информацию о своих event’ах, есть всего 3 вида:

Вместе с next‘ом приходит элемент, который мы отправляли и все события посланные нами, error посылается как понятно из названия в случае ошибки, а completed в случае, когда наш observable отослал все данные и завершает работу.

Мы можем создать более детального наблюдателя subscriber’а и получить более удобный вид для обработки всех событий.

В observable можно создавать последовательность не только из одной строки, да и вообще не только из строк, мы можем положить туда любой тип данных.

Observable можно создать из массива значений.

У одного observable может быть сколь угодно много subscriber’ов. А теперь терминология, что такое Observable?

Observable — это основа всего Rx, которая асинхронно генерирует последовательность неизменяемых данных и позволяет подписываться на нее другим.

Disposing

Теперь, когда мы умеем создавать последовательность и подписываться на них, необходимо разобраться с такой штукой, как disposing.

Важно помнить, что Observable это «холодный» тип, то есть наш observable не «испускает» никаких событий, пока на него не подпишутся. Observable существует до тех пор, пока он не пошлет сообщение об ошибке (error) или сообщение о завершении (completed). Если мы хотим явно отменить подписку, то можем сделать следующее.

Есть более красивый правильный вариант.

Таким образом мы добавляем нашу подписку в сумку утилизации или в DisposeBag.
Для чего это нужно? Если вы, используя подписку, не добавите ее в сумку или явно не вызовете dispose, ну или в крайнем случае не приведете каким-то образом observable к завершению, то скорее всего вы получите утечку памяти. DisposeBag вы будете использовать очень часто в своей работе с RxSwift.

Operators

В функционально-реактивном программировании (ФРП далее) есть много встроенных операторов для трансформации элементов observable. Существует сайт rxmarbles, на нем можно посмотреть работу и эффект всех операторов, ну а мы все же рассмотрим некоторые из них.

Оператор map используется очень часто и думаю, что знаком многим, с его помощью мы трансформируем все полученные элементы.
Пример:

Что получим в консоли:

Мы берем каждый элемент последовательности и создаем новую результирующую последовательность. Чтобы было более понятно, что происходит лучше записать подробнее.

Что такое «$0»?

$0 это название элемента по умолчанию, мы можем использовать в методах сокращенную и полную запись, чаще всего используется сокращенная запись.

Согласитесь, что сокращенная форма записи куда проще, так?

Filter

Оператор filter позволяет нам отфильтровать испускаемые нашим observable’ом данные, то есть при подписке мы не будем получать ненужные нам значения.
Пример:

Что мы получим в консоль?

Как мы видим, в консоли у нас только те значения, что удовлетворяют нашим условиям.

Кстати, операторы можно комбинировать, вот как это выглядело бы, если бы мы захотели применить сразу и оператор фильтрации и оператор map.

Консоль:

Distinct

Еще один отличный оператор, который связан с фильтрацией, оператор disctinct позволяет пропускать только измененные данные, лучше всего сразу обратиться к примеру и все станет понятно.

В консоль мы получим следующее:

то есть в случае, если нынешний элемент последовательности идентичен предыдущему, то он пропускается и так происходит до тех пор, пока не появится отличный от предыдущего элемент, это очень удобно при работах скажем с UI, а именно с таблицей, в случае если нам пришли данные, такие же, как мы имеем сейчас, то reload’ить таблицу не следует.

TakeLast

Очень простой оператор takeLast, мы берем n-ое количество элементов с конца.

В консоль получим следующее:

Throttle и Interval

Тут я решил взять сразу 2 оператора, просто потому что с помощью второго, легко можно показать работу первого.

Оператор throttle позволяет взять паузу между захватом передаваемых значений, очень просто пример, вы пишите реактивное приложение, используете строку поиска и не хотите каждый раз после ввода данных пользователем либо перезагружать таблицу, либо лезть на сервер, поэтому вы используете throttle и таким образом говорите, что хотите брать данные пользователя раз в 2 секунды (пример, можно поставить любой интервал) и снижаете расход ресурсов на лишнюю обработку, как это работает и описывается в коде? Смотрите ниже пример.

Оператор interval заставляет observable генерировать значения каждые 0,5 секунды с шагом 1 начиная с 0, вот такой простой таймер у Rx. Получается раз значения генерируются каждые 0,5 секунды, то в секунду генерируется 2 значения, нехитрая арифметика, а оператор throttle ждет секунду и берет последнее значение.

Debounce

Debounce очень похож на предыдущий оператор, но чуть более умнее, на мой взгляд. Оператор debounce ждет n-ое количество времени и в случае, если со старта его таймера не было изменений, то берет последнее значение, если же мы пошлем значение, то таймера перезапустится снова. Это как раз очень полезно для ситуации описанной в предыдущем примере, пользователь вводит данные, мы ждем когда он закончит (если пользователь бездействует секунду или полторы), а потом начинаем выполнять какие-то действия. Поэтому если мы просто поменяем оператор в предыдущем коде, то значений мы не получим в консоль, потому что debounce будет ждать секунду, но каждые 0,5 секунды будет получать новое значение и перезапускать свой таймер, таким образом мы ничего не получим. Посмотрим пример.

На этом этапе предлагаю закончить с операторами, в фреймворке RxSwift их очень много, нельзя сказать, что все из них очень нужны в повседнейной жизни, но знать о их существовании все же надо, поэтому желательно ознакомиться с полным перечнем операторов на сайте rxmarbles.

Scheduler

Очень важная тема, которую в этой статье я бы хотел затронуть, это scheduler. Scheduler, позволяют нам запускать наши observable на определенных потоках и в них есть свои тонкости. Начнем, существует 2 вида установить observable scheduler — [observeOn]() и [subscribeOn]().

SubscribeOn

SubscribeOn отвечает за то, в каком потоке будет выполняться весь процесс observable до того момента, как его event’ы дойдут до обработчика (подписчика).

ObserveOn

Как можно догадаться observeOn отвечает за то, в каком потоке будут обрабатываться принятые подписчиком event’ы.

Это очень крутая штука, потому что мы можем очень легко поставить загрузку чего-либо из сети в background поток, а при получении результат перейти в main поток и как-то воздействовать на UI.

Давайте посмотрим, как это работает на примере:

В консоль мы получим:

Мы видим, что observable создавался в background потоке, а обрабатывали данные мы в main потоке. Это полезно при работе с сетью к примеру:

Таким образом запрос будет выполняться в background потоке, а вся обработка ответа будет происходить в main. На данном этапе пока рано говорить, что за rx метод у URLSession нарисовался вдруг, это будет рассмотрено позднее, данный код был приведен в качестве примера использования Scheduler, кстати, в консоль мы получим следующий ответ.

В финале давайте посмотрим еще что за data нам пришла, для этого придется выполнить проверку, чтобы не начать парсить сообщение completed случайно.

Мы проверяем, что event не сообщение о завершении работы observable и не ошибка пришедшая от него, хотя можно было реализовать другой метод подписки и обработать все эти виды event’ов отдельно, но это вы уже сможете сделать самостоятельно, а в консоль мы получим следующее.

Subjects

Переходим к горячему, а именно от «холодных» или «пассивных» observable к «горячим» или «активным» observable, которые зовутся subject’ами. Если до этого наши observable начинали свою работу только после подписки на них и у вас был вопрос в голове «ну и зачем мне все это надо?», то Subject’ы работают всегда и всегда шлют полученные данные.

Как это? В случае с observable мы заходили в поликлинику, шли к злой бабульке на ресепшене регистратуре, подходили и спрашивали в какой кабинет нам идти, тогда бабуленция нам отвечала, в случае с subject’ами, бабуленция стоит и слушает расписание и состояние врачей по больнице и как только получает информацию о перемещении какого-либо врача сразу говорит это, спрашивать у бабуленции что-то бесполезно, мы можем просто подойти, послушать ее, уйти, а она продолжит говорить, что-то увлекся со сравнениями, давайте уже к коду.

Создадим один subject и 2 подписчиков, первого создадим сразу после subject’а, пошлем subject’у значение, а потом создадим второго и пошлем еще парочку значений.

Что мы увидим в консоли? правильно, первый успел получить первый event, а второй нет.

Уже больше подходит под ваше представление о реактивном программировании?
Subject’ы бывают нескольких видов, все они отличаются тем, как они шлют значения.

PublishSubject — самый простой, ему без разницы на все, он просто рассылает всем подписчикам то, что ему пришло и забывает об этом.

ReplaySubject — а вот это самый ответственный, при создании мы указываем ему размер буфера (сколько значений будет запоминать), в результате он хранит в памяти последние n значений и посылает их сразу новому подписчику.

BehaviorSubject — не такой пофигист, как предыдущий, он имеет стартовое значение и он запоминает последнее значение и посылает его сразу после подписки подписчика.

Заключение

Это была вводная статья, написанная для того, чтобы вы знали основы и могли в последующем отталкиваться от них. В следующих статьях мы рассмотрим как работать с помощью RxSwift с UI компонентами iOS, создание расширений для UI компонентов.

Не RxSwift’ом едины

Реактивное программирование реализовано не только в библиотеке RxSwift, есть несколько реализаций, вот самые популярные из них ReacktiveKit/Bond, ReactiveSwift/ReactiveCocoa. У всех у них есть небольшие различия в реализации под капотом, но на мой взгляд лучше начинать свое познание «реактивщины» именно с RxSwift, так как он наиболее популярный среди них и по нему будет больше ответов в великом гугле, но после того, как вы вникните в суть данной концепции, можно выбирать библиотеки на свой вкус и цвет.
Автор статьи: Гречихин Павел

Источник

Знакомство с RxSwift: примеры кода реактивного программирования на языке Swift

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Около года назад наш iOS-разработчик компании Noveo, Александр, заинтересовался RxSwift. Столкнувшись с нехваткой документации, Саша решил самостоятельно упорядочить все приобретенные в ходе изучения фреймворка знания — для себя и для других. Результатом стала одна из его статей о Swift 2.2. Со времени ее публикации, конечно, и RxSwift, и сам Swift эволюционировали, и материал нуждался в обновлении, и другой iOS-разработчик из Noveo, Михаил, адаптировал материал для Swift 3. После редакции статья заиграла свежими красками, и на этом мы передаем слово нашим коллегам.

Заинтересовавшись темой функционального программирования, я встал на распутье: какой фреймворк выбрать для ознакомления? ReactiveCocoa — ветеран в iOS-кругах, информации по нему вдоволь. Но он вырос из Objective-C, и хотя это не является проблемой, все же в данный момент я в основном пишу на Swift, и хотелось бы взять решение, изначально спроектированное с учетом всех плюшек этого языка. RxSwift же — порт Reactive Extensions; последний, конечно, имеет долгую историю, но сам порт свежий и написан как раз под Swift. На нем я и решил остановиться.

Как выяснилось, документация по RxSwift несколько специфична: описание всех команд ведет на http://reactivex.io/, а там в основном дается общая информация, у разработчиков еще не дошли руки сделать документацию именно для RxSwift, что не всегда удобно. Некоторые команды имеют тонкости в реализации, а есть такие, о которых в общей документации нет ничего, кроме упоминания.

Прочитав все главы вики с гитхаба RxSwift, я решил сразу поразбираться с официальными примерами; тут-то и стало ясно, что с RX такое не пройдет, нужно хорошо понимать основы, иначе будешь как мартышка с копипастом гранатой. Я начал разбирать самые сложные для понимания команды, а потом перешел к тем, что были вроде и понятны, но задавая себе вопросы по ним, я лишь догадывался, как верно ответить, и уверенности в моих ответах у меня не было.

В общем, я решил проработать все операторы RxSwift. Лучший способ что-то понять в программировании — запустить код и посмотреть, как он отработает. Учитывая специфику реактивного программирования, лучше дополнить это схемами (они бывают очень полезны), ну и кратким описанием на русском. Закончив сегодня работу, я подумал, что грех не поделиться результатами с тем, кто лишь присматривается к теме реактивного программирования.

Много картинок и текста ниже, очень много!

Предварительно я рекомендую просмотреть официальную документацию, у меня передана основная суть и специфика RxSwift команд, а не основы.
Так же можно «поиграться» с шариками в схемах, так называемые RxMarbles, есть бесплатная версия под iPhone/iPad.

Итак, в этой статье я рассмотрю все (ну или почти все) команды RxSwift, дам для каждой краткое описание, схему (если это имеет смысл), код, результат выполнения, а при необходимости сделаю комментарии по выводу в лог результатов выполнения кода.
В статье заголовок каждой команды — ссылка на на официальную документацию, т.к. я не ставил перед собой цели перевести все нюансы по командам.
Вот и ссылка конкретно на PDF, где в виде mindMap собраны все команды, что позволяет быстро просмотреть их все. Кусочки кода в PDF приложены для того, чтобы увидеть, как и с каким параметрами нужно работать с командой. Изначально ради этого PDF я все и затеял — чтобы иметь под рукой документ, в котором наглядно видны все команды с их схемами. PDF получился огромным (в плане рабочего пространства, а не веса), но я проверял, даже на iPad 2 все нормально просматривается.

Обо всех ошибках просьба писать в личку, объем работ оказался слегка великоват, после четвертой вычитки текста мои глаза меня прокляли.

Что ж, надеюсь, моя работа кому-то пригодится. Приступим.

Источник

Узнать и овладеть ⚔️ основами RxSwift за 10 минут

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Узнать и овладеть ⚔️ основами RxSwift за 10 минут

Каждый разработчик слышал об Rx, будь то на последней конференции разработчиков или во время чтения публикации в блоге вроде этой 😎. Практически невозможно умудриться не услышать о реактивном программировании, но что же оно всё-таки собой представляет? Заглянем в интернет:

Реактивное программирование — парадигма программирования, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных с помощью применяемых языков программирования, а также то, что нижележащая модель исполнения должна автоматически распространять изменения благодаря потоку данных. — Википедия

Если честно, я считаю, что большинству людей, как и мне, такое объяснение не даст ни малейшего представления о том, чем, собственно, является реактивное программирование. Поэтому я попытаюсь создать своё, простое и понятное введение в этот современный подход к разработке ПО, применяя версию Rx для языка “Swift” — RxSwift.

Первое, что нужно понять, — всё в RxSwift является либо наблюдаемой последовательностью, либо чем-то, что оперирует распространяемыми наблюдаемой последовательностью событиями или подписывается на них.

Массивы, строки и словари в RxSwift преобразуются в наблюдаемые последовательности. Вы можете создать наблюдаемую последовательность из любого объекта, соответствующего протоколу Sequence стандартной библиотеки языка Swift.

Попробуем создать несколько наблюдаемых последовательностей:

Подписаться на наблюдаемые последовательности можно, вызвав

Переданный блок будет принимать уведомления обо всех событиях, распространяемых данной последовательностью.

Наблюдаемые последовательности могут распространять ноль или более событий за время своего существования.

В RxSwift событие — это просто перечисление (Enumeration Type) с тремя возможными состояниями:
.next(value: T) — Когда в наблюдаемой последовательности возникает новое значение или набор значений, она отправляет событие “next” своим подписчикам, как вы могли видеть в примере выше. Ассоциированное значение будет содержать актуальное значение из последовательности.
.error(error: Error) — При обнаружении ошибки последовательность распространит событие “error”. Также это приведёт к уничтожению последовательности.
.completed — Если последовательность завершилась нормально, она отправляет подписчикам событие “completed”.

Если вы хотите отменить подписку, вы можете сделать это, вызвав её метод dispose. Вы также можете добавить подписку в Disposebag (“корзину”), которая автоматически отменит подписку при выполнении метода deinit экземпляра DisposeBag. Кроме того, вы можете подписаться только на конкретное событие. Например, если вы хотите просто получать сообщения об ошибках, распространяемые последовательностью, вы можете использовать subscribe(onError:(Error->())).

Фрагмент кода, иллюстрирующий всё, что мы уже успели обсудить:

2. Subject’ы 📫

Subject — это особый вид наблюдаемой последовательности, вы можете подписаться и динамически добавлять к нему элементы. В настоящее время существует 4 различных вида Subject’ов в RxSwift

В рамках данной статьи я рассматриваю только работу PublishSubject. Обратитесь к дополнительному материалу на GitHub’е, если вы хотите узнать больше о других subject-типах. Они отличаются, в основном, только количеством прошлых событий, распространяемых и получаемых подписчиками по первоначальной подписке.

Behaviour & Variable: 1

Вначале нам нужно создать экземпляр PublishSubject. Делается это очень просто: можем использовать для этого инициализатор по умолчанию.

Мы можем добавлять новые значения к этой последовательности с помощью функции onNext(). onCompleted() завершает последовательность, а onError(error) приводит к распространению события-ошибки. Давайте добавим некоторые значения в наш PublishSubject.

Если вы подпишетесь на этот subject после добавления “Hello” и “World” с помощью onNext(), вы не получите два этих значения через события. В отличие от BehaviourSubject, который бы получил “World”, поскольку это самое последнее событие.

Теперь давайте создадим подписку и добавим новые значения в Subject.

Ещё мы создадим вторую подписку и добавим ещё значений.

Обратите внимание на комментарии, чтобы понять, что именно происходит в коде.

Мои поздравления 🎉. Если вы дочитали до этого момента, значит вы ознакомились с основами RxSwift. Многое ещё предстоит изучить, но в Rx всё базируется на этих простых принципах. Можете сделать сейчас небольшой перерыв и немного поэкспериментировать с этими принципами, чтобы как следует их понять. Если вы готовы, то давайте продолжим, поскольку впереди ещё очень много интересного.

3. Marble Diagrams 🙌🏼

Если вы работаете с RxSwift или вообще с Rx, вам стоит освоить Marble Diagrams (“шариковые диаграммы”). Эти диаграммы визуализируют изменения в наблюдаемых последовательностях. Диаграмма состоит из входящего потока (input stream) сверху, исходящего потока (output stream) снизу и фактической преобразующей функции посередине.

Например, давайте рассмотрим операцию, которая задерживает распространяемые события наблюдаемой последовательности на 150 миллисекунд. Не обращайте внимания на параметр “scheduler”, о нём я расскажу немного позже:

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Достаточно просто для понимания, да?

Существуют замечательные open source проекты как для iOS, так и для Android, позволяющие поэкспериментировать в интерактивном режиме с такими диаграммами на ваших мобильных устройствах. Поиграйтесь с ними, и обещаю, что вы разберётесь в Rx очень быстро.

4. Преобразования ⚙️

Иногда нам может потребоваться преобразовать, объединить или отфильтровать элементы, распространяемые наблюдаемой последовательностью до того, как их получит подписчик. Я познакомлю вас с базовыми операторами преобразования, расскажу кое-что о фильтрах и о возможностях объединения последовательностей. В заключение я покажу, как производить преобразование, объединение и др. в разных потоках.

4.1 Map

Чтобы преобразовать распространяемые наблюдаемой последовательностью элементы до того, как они попадут к своим подписчикам, необходимо использовать оператор map. Допустим, имеется преобразование, умножающее каждое значение последовательности на 10 перед распространением.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

4.2 FlatMap

Представим наблюдаемую последовательность, состоящую из объектов, которые сами являются наблюдаемыми, и допустим, что мы хотим создать из них новую последовательность. В таких случаях в игру вступает FlatMap. FlatMap объединит распространение итоговых наблюдаемых и распространит эти объединённые результаты как отдельную последовательность.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

4.3 Scan

Scan принимает исходное значение и используется для агрегирования значений аналогично reduce в Swift’е.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

4.4 Buffer

Оператор Buffer преобразует наблюдаемого, распространяющего элементы, в наблюдаемого, который распространяет буферизированные коллекции этих элементов.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

5.Filter 🚬

Если на следующие события необходимо реагировать только исходя из определённого условия, используйте оператор filter.

5.1 Filter

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

5.2 DistinctUntilChanged

Если вы хотите распространять события next только в случае, если значение изменилось, используйте distinctUntilChanged.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Другие операторы фильтра, которые стоит опробовать:

6. Combine 💑

Объединение последовательностей — широко распространённая задача. RxSwift предоставляет для этого множество операторов. Вот три из них:

6.1 StartWith

Если вы хотите, чтобы наблюдаемый распространял определённую последовательность элементов до того, как начнёт распространять элементы, которые от него ожидаются в обычном режиме, используйте оператор startWith.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

6.2 Merge

Существует возможность объединить выдачу от нескольких наблюдаемых с помощью оператора Merge, чтобы они вели себя как единый наблюдаемый.

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

6.3 Zip

reactive swift с чего начать. Смотреть фото reactive swift с чего начать. Смотреть картинку reactive swift с чего начать. Картинка про reactive swift с чего начать. Фото reactive swift с чего начать

Используйте метод Zip, если хотите объединить распространяемые разными наблюдаемыми последовательностями элементы в одну наблюдаемую последовательность. Zip срабатывает в строгой последовательности, то есть первыми двумя элементами, распространёнными Zip’ом, будет комбинация первого элемента первой последовательности и первого элемента второй последовательности. Также имейте в виду, что Zip распространит только количество элементов, равное наименьшему числу элементов, распространяемых исходными наблюдаемыми.

Другие операторы комбинирования, которые стоит опробовать:

7. Сторонние действия 👉

Если вы хотите зарегистрировать callback’и, которые будут исполняться при определённых событиях в наблюдаемой последовательности, используйте оператор doOn. Он не изменяет распространяемые элементы, а просто передаёт их.

Вы можете использовать:

8. Schedulers

Операторы работают в том же потоке, где была создана подписка. В RxSwift используются scheduler’ы (диспетчеры), чтобы заставить операторы производить свою работу в конкретной очереди. Также вы можете заставить подписку происходить в определённой очереди. Используйте subscribeOn и observeOn для таких задач. Если вы знакомы с концепцией operation-queues или dispatch-queue, то здесь для вас не будет ничего нового. Scheduler может быть последовательным (serial) или гоночным (concurrent) аналогично GCD или OperationQueue. В RxSwift есть пять типов scheduler’ов:

Вот пример кода, демонстрирующий, как можно наблюдать за чем-то в режиме гонки в фоновой очереди и при этом подписаться на главную очередь.

Подытожим 🎁

Поздравляю, вы освоили основы RxSwift. Удачного программирования! 🎉

В скором будущем ожидайте статью “Изучите и освойте RxCocoa”…

Добавляйте меня в github‘е, twitter‘е, linkedin‘е или xing‘е, если у вас есть какие-то вопросы. Если вам нравится электронная музыка, можете также послушать мои треки на SoundCloud 😉

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *