<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0">

<channel>

<title>.iOS</title>
<link>https://blog.adeveloper.ru/</link>
<description>коротко</description>
<generator>E2 (v2858; Aegea)</generator>

<item><title>Разработка субагентов для Qwen Code: расширяем возможности AI-программиста</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/razrabotka-subagentov-dlya-qwen-code-rasshiryaem-vozmozhnosti-ai/</guid><link>https://blog.adeveloper.ru/all/razrabotka-subagentov-dlya-qwen-code-rasshiryaem-vozmozhnosti-ai/</link><description>&lt;h2&gt;Введение&lt;/h2&gt;
&lt;p&gt;Qwen Code — это открытый AI-агент для терминала, оптимизированный для моделей семейства Qwen3-Coder. Он помогает разработчикам понимать крупные кодовые базы, автоматизировать рутинные операции и ускорять процесс разработки. Однако настоящая сила этого инструмента раскрывается через систему &lt;b&gt;субагентов (Subagents)&lt;/b&gt; — специализированных ИИ-ассистентов, которые берут на себя определённые типы задач, позволяя строить полноценные мультиагентные системы для программирования.&lt;/p&gt;
&lt;h2&gt;Что такое субагенты и зачем они нужны&lt;/h2&gt;
&lt;p&gt;Субагенты в Qwen Code — это независимые ИИ-ассистенты, каждый из которых настраивается под конкретную специализацию: написание тестов, рефакторинг кода, генерацию документации, код-ревью и многое другое. Они представляют собой изолированные экземпляры агентов с собственным контекстом, набором инструментов и системным промптом.&lt;/p&gt;
&lt;p&gt;Ключевые характеристики субагентов:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Специализация&lt;/b&gt; — каждый агент настраивается с помощью фокусированного системного промпта на определённый тип работы.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Изоляция контекста&lt;/b&gt; — у субагента собственная история диалога, независимая от основного чата, что предотвращает «загрязнение» контекста.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Контролируемый доступ к инструментам&lt;/b&gt; — можно ограничить набор инструментов, доступных каждому субагенту.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Автономность&lt;/b&gt; — получив задачу, субагент работает самостоятельно до завершения.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Параллельное выполнение&lt;/b&gt; — можно одновременно запускать несколько субагентов для независимых задач.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Архитектура системы субагентов&lt;/h2&gt;
&lt;p&gt;С архитектурной точки зрения система субагентов в Qwen Code построена вокруг `SubagentManager`, который управляет жизненным циклом конфигураций агентов. Конфигурации хранятся в виде Markdown-файлов с YAML frontmatter — такой формат удобен для редактирования в любом текстовом редакторе и легко читается человеком.&lt;/p&gt;
&lt;p&gt;Субагенты могут храниться на нескольких уровнях:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Проектный уровень&lt;/b&gt; (`.qwen/agents/`) — наивысший приоритет, агенты доступны только в рамках конкретного проекта.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Пользовательский уровень&lt;/b&gt; `~/.qwen/agents/` — персональные агенты, доступные во всех проектах.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Уровень расширений&lt;/b&gt; — агенты, предоставляемые установленными расширениями.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;При запуске субагента через инструмент `Task` происходит следующее:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Основной агент идентифицирует подзадачу, подходящую для делегирования.&lt;/li&gt;
&lt;li&gt;Создаётся специализированный субагент с описанием задачи, релевантным контекстом, доступом к инструментам и независимой историей диалога.&lt;/li&gt;
&lt;li&gt;Субагент автономно выполняет задачу, вызывая инструменты по мере необходимости.&lt;/li&gt;
&lt;li&gt;По завершении возвращается результат, созданные артефакты и статистика использования токенов.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Создание первого субагента&lt;/h2&gt;
&lt;p&gt;Быстрый старт через CLI-команды&lt;/p&gt;
&lt;p&gt;Самый простой способ создать субагента — воспользоваться встроенной командой в Qwen Code:&lt;/p&gt;
&lt;pre&gt;
/agents create
&lt;/pre&gt;
&lt;p&gt;Эта команда запускает интерактивный мастер, который шаг за шагом проведёт вас через процесс создания специализированного агента. Для управления существующими агентами используется команда:&lt;/p&gt;
&lt;pre&gt;
/agents manage
&lt;/pre&gt;
&lt;p&gt;Она открывает диалоговое окно, где можно просматривать и настраивать уже созданные конфигурации.&lt;/p&gt;
&lt;h2&gt;Ручное создание через Markdown-файл&lt;/h2&gt;
&lt;p&gt;Для более тонкой настройки субагенты можно создавать вручную. Файл конфигурации использует формат Markdown с YAML frontmatter. Создайте файл, например, `.qwen/agents/code-reviewer.md`, со следующим содержимым:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;```yaml
---
name: code-reviewer
description: Специализируется на ревью кода, анализе качества и выявлении проблем безопасности
tools:
  - read
  - grep
  - glob
  - web_fetch
model: inherit
---
# Code Reviewer Agent

Ты — эксперт по код-ревью, специализирующийся на:
- Выявлении уязвимостей безопасности
- Анализе производительности
- Проверке соответствия стилю кода и лучшим практикам
- Оценке читаемости и поддерживаемости

Твоя задача — предоставлять конкретные, actionable рекомендации по улучшению кода. 
При проверке всегда обращай внимание на контекст проекта и существующие конвенции.

Возвращай результат в формате:
1. Общая оценка
2. Критические проблемы (если есть)
3. Рекомендации по улучшению
```&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Рассмотрим структуру конфигурации подробнее:&lt;/p&gt;
&lt;div class="e2-text-table"&gt;
&lt;table cellpadding="0" cellspacing="0" border="0"&gt;
&lt;tr&gt;
&lt;td&gt;Поле&lt;/td&gt;
&lt;td&gt;Тип&lt;/td&gt;
&lt;td&gt;Описание&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;b&gt;name&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;string&lt;/td&gt;
&lt;td style="text-align: left"&gt;Уникальный идентификатор (2-50 символов, буквы, цифры, дефисы)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;b&gt;description&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;string&lt;/td&gt;
&lt;td style="text-align: left"&gt;Краткое описание назначения, используется для автоматического делегирования задач&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;b&gt;tools&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;string[]&lt;/td&gt;
&lt;td style="text-align: left"&gt;Опциональный список разрешённых инструментов; если не указан — наследуются все доступные&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;b&gt;model&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;string&lt;/td&gt;
&lt;td style="text-align: left"&gt;Выбор модели&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;b&gt;systemPrompt&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;string&lt;/td&gt;
&lt;td style="text-align: left"&gt;Тело Markdown-файла — это и есть системный промпт, определяющий поведение агента&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2&gt;Типовые шаблоны субагентов&lt;/h2&gt;
&lt;p&gt;Вот несколько распространённых паттернов субагентов, которые можно взять за основу:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Test Writer&lt;/b&gt; — для генерации тестов:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;```yaml
---
name: test-writer
description: Пишет юнит-тесты и интеграционные тесты с высоким покрытием
tools:
  - read
  - grep
  - write_file
  - bash
---
Ты — специалист по тестированию. Пишешь unit-тесты с высоким покрытием, интеграционные тесты для критических путей, обрабатываешь граничные случаи. Следуй принятым в проекте конвенциям тестирования.
```&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Documentation Writer&lt;/b&gt; — для генерации документации:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;```yaml
---
name: docs-writer
description: Создаёт и обновляет техническую документацию
tools:
  - read
  - grep
  - glob
  - write_file
---
Ты — технический писатель. Создаёшь понятную API-документацию, примеры использования, архитектурные диаграммы в Markdown и README-файлы. Придерживайся стиля существующей документации.
```&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Refactoring Specialist&lt;/b&gt; — для рефакторинга кода:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;```yaml
---
name: refactor-specialist
description: Улучшает структуру кода, устраняет запахи, выделяет переиспользуемые компоненты
tools:
  - read
  - grep
  - edit
  - bash
---
Ты — эксперт по рефакторингу. Идентифицируешь проблемы кода, выделяешь повторно используемые компоненты, улучшаешь именование и структуру. Делай небольшие, безопасные изменения.
```&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h2&gt;Использование субагентов&lt;/h2&gt;
&lt;p&gt;Автоматическое делегирование&lt;/p&gt;
&lt;p&gt;После настройки субагентов Qwen Code может автоматически делегировать им подходящие задачи. Достаточно сформулировать запрос, соответствующий специализации одного из агентов:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;*Пользователь*: «Напиши исчерпывающие тесты для модуля аутентификации»&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;*AI*: «Я делегирую эту задачу твоему субагенту-специалисту по тестированию».&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Основной агент анализирует запрос, сопоставляет его с полем `description` доступных субагентов и принимает решение о делегировании.&lt;/p&gt;
&lt;h2&gt;Явное делегирование через инструмент Task&lt;/h2&gt;
&lt;p&gt;Для программного или более точного управления можно использовать инструмент `Task` напрямую:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;task(
  description: &amp;quot;Рефакторинг кода&amp;quot;,
  prompt: &amp;quot;Выполни рефакторинг модуля аутентификации в src/auth/, заменив колбэки на async/await. Убедись, что все тесты проходят, и обнови документацию.&amp;quot;,
  subagent_type: &amp;quot;general-purpose&amp;quot;
)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Инструмент принимает три обязательных аргумента:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;`description` (string) — короткое описание задачи (3-5 слов) для отображения пользователю.&lt;/li&gt;
&lt;li&gt;`prompt` (string) — подробные инструкции для автономного выполнения.&lt;/li&gt;
&lt;li&gt;`subagent_type` (string) — тип субагента, соответствующий одной из доступных конфигураций.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Параллельное выполнение задач&lt;/h2&gt;
&lt;p&gt;Одно из главных преимуществ субагентов — возможность параллельного выполнения независимых задач:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;```javascript
// Параллельный запуск код-ревью и выполнения тестов
task(
  description: &amp;quot;Код-ревью&amp;quot;,
  prompt: &amp;quot;Проверь последние изменения в модуле управления пользователями на качество кода, безопасность и соответствие лучшим практикам.&amp;quot;,
  subagent_type: &amp;quot;code-reviewer&amp;quot;
)

task(
  description: &amp;quot;Запуск тестов&amp;quot;,
  prompt: &amp;quot;Выполни полный набор тестов и проанализируй ошибки. Предоставь сводку по покрытию и рекомендации по улучшению.&amp;quot;,
  subagent_type: &amp;quot;test-runner&amp;quot;
)
```&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Субагенты работают независимо, и их результаты возвращаются по мере завершения. В режиме реального времени можно отслеживать статус выполнения, отдельные вызовы инструментов и возможные ошибки.&lt;/p&gt;
&lt;p&gt;#Продвинутые техники и лучшие практики&lt;/p&gt;
&lt;p&gt;Проектирование эффективных описаний&lt;/p&gt;
&lt;p&gt;Поле `description` играет критическую роль в автоматическом делегировании — именно по нему основной агент решает, подходит ли субагент для задачи. Рекомендации:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Используйте глаголы действия: «Пишет тесты...», «Анализирует код...», «Рефакторит...».&lt;/li&gt;
&lt;li&gt;Указывайте конкретную предметную область.&lt;/li&gt;
&lt;li&gt;Делайте описание достаточно подробным, чтобы отличить агента от похожих по назначению.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Стратегия ограничения инструментов&lt;/h2&gt;
&lt;p&gt;Ограничение доступных инструментов — мощный механизм контроля и безопасности. Например:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Read-only агенты&lt;/b&gt; (code-reviewer, docs-writer) — только `read`, `grep`, `glob`, `web_fetch`. Это предотвращает случайные изменения кода.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Агенты с правом записи&lt;/b&gt; (test-writer, refactor-specialist) — добавляются `write_file`, `edit`.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Агенты с полным доступом&lt;/b&gt; (general-purpose) — могут использовать `bash` для выполнения команд и тестов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Такой подход минимизирует риски и заставляет субагента фокусироваться на своей специализации.&lt;/p&gt;
&lt;h2&gt;Работа с переменными в промптах&lt;/h2&gt;
&lt;p&gt;Системные промпты поддерживают шаблонизацию с использованием переменных `${variable}`. Это позволяет создавать гибкие конфигурации, адаптирующиеся под контекст проекта:&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;```yaml
---
name: project-specific-agent
description: Адаптируется к технологическому стеку проекта
---
Ты работаешь над проектом ${PROJECT_NAME}. Технологический стек: ${TECH_STACK}. 
Следуй код-стайлу, описанному в ${STYLE_GUIDE}.
```&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h2&gt;Интеграция с расширениями&lt;/h2&gt;
&lt;p&gt;Субагенты можно упаковывать в расширения Qwen Code. Для этого в расширении создаётся директория `agents/`, а в `qwen-extension.json` указывается поле `agents`. При активации расширения агенты автоматически становятся доступными и появляются в диалоге `/agents manage` в секции «Extension Agents».&lt;/p&gt;
&lt;h2&gt;Отладка и мониторинг&lt;/h2&gt;
&lt;p&gt;При работе с субагентами полезно:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Использовать `/agents manage` для просмотра всех доступных конфигураций.&lt;/li&gt;
&lt;li&gt;Отслеживать прогресс выполнения в реальном времени через UI Qwen Code.&lt;/li&gt;
&lt;li&gt;Анализировать возвращаемую субагентами статистику по использованию токенов.&lt;/li&gt;
&lt;li&gt;При проблемах с делегированием явно указывать имя агента в запросе: «Используй [Имя Агента] для [Задача]».&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Заключение&lt;/h2&gt;
&lt;p&gt;Субагенты превращают Qwen Code из простого AI-ассистента в полноценную мультиагентную платформу для разработки. Возможность создавать специализированных агентов, контролировать их инструменты и запускать задачи параллельно открывает новые горизонты автоматизации программирования.&lt;/p&gt;
&lt;p&gt;Ключевые преимущества использования субагентов:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Параллелизация&lt;/b&gt; сложных задач на независимые подзадачи.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Специализация&lt;/b&gt; — каждый агент заточен под конкретный тип работы.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Изоляция контекста&lt;/b&gt; — чистота основного диалога и чёткое разделение ответственности.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Переиспользуемость&lt;/b&gt; — один раз настроенный агент работает во всех проектах.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Безопасность&lt;/b&gt; — тонкий контроль над тем, какие инструменты доступны каждому агенту.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Система субагентов в Qwen Code продолжает активно развиваться — в последних версиях появились улучшения в обработке системных промптов, поддержка проектных настроек и оптимизации параллельного выполнения. Следите за обновлениями и экспериментируйте с созданием собственных специализированных агентов для своих рабочих процессов.&lt;/p&gt;
</description><pubDate>Wed, 15 Apr 2026 12:14:15 +0300</pubDate></item><item><title>Мыслетопливо</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/mysletoplivo/</guid><link>https://blog.adeveloper.ru/all/mysletoplivo/</link><description>&lt;p&gt;Конечно, нередко нам кажется, что заканчивается именно время, но на поверку это оказывается следствием опустошения бачка с мыслетопливом: сначала иссякает оно, потом врубается медленное мышление, как результат мы начинаем «тупить» и испытывать затруднения даже с элементарными вещами, делая их во много раз дольше обычного.&lt;br /&gt;
...&lt;/p&gt;
</description><pubDate>Mon, 07 Sep 2020 20:58:51 +0300</pubDate></item><item><title>UML: Связи между сущностями (объектами)</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/uml-svyazi-mezhdu-suschnostyami-obektami/</guid><link>https://blog.adeveloper.ru/all/uml-svyazi-mezhdu-suschnostyami-obektami/</link><description>&lt;p&gt;Основные связи при проектировании Архитектуры&lt;/p&gt;
&lt;div class="e2-text-table"&gt;
&lt;table cellpadding="0" cellspacing="0" border="0"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;img src="/pictures/3.png" width="100px" &gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Реализация протокола/интерфейса или Имплементация.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;img src="/pictures/dep.png" width="100px" &gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Явная связь&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;img src="/pictures/composition.png" width="100px" &gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Композиция — внутренняя зависимость&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;img src="/pictures/aggregation.png" width="100px" &gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Агрегация (инъекция зависимости) внешняя зависимость&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Понизить связанность кода путём скрытия конкретной реализции за протоколами и для этого в UML диаграмме нам подходит такая связь &lt;img src="/pictures/3.png" width="100px" &gt;...&lt;/p&gt;
&lt;p&gt;Например: у нас есть протокол и объекты которые на него подписаны (реализующие этот протокол).&lt;br /&gt;
&lt;img src="/pictures/implementaion_ref.png" width="500px" &gt;&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;protocol Configurable {
   func configure(with model: Model)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;pre&gt;

&lt;/pre&gt;
</description><pubDate>Wed, 19 Feb 2020 17:49:01 +0300</pubDate></item><item><title>RxSwift</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/rxswift-2/</guid><link>https://blog.adeveloper.ru/all/rxswift-2/</link><description>&lt;p&gt;Содержание&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.adeveloper.ru/all/driver/"&gt;Driver&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Mon, 18 Nov 2019 08:46:16 +0300</pubDate></item><item><title>Driver</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/driver/</guid><link>https://blog.adeveloper.ru/all/driver/</link><description>&lt;p&gt;&lt;img src="https://cdn.pixabay.com/photo/2013/08/12/11/10/dog-171773_960_720.jpg" width="300" /&gt;&lt;/p&gt;
&lt;h2&gt;Дравйвер&lt;/h2&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;классная вещь в RxSwift, позволяет:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Восстанавливаться от ошибок.&lt;/li&gt;
&lt;li&gt;Является Observable&lt;/li&gt;
&lt;li&gt;Автоматически переводит подписку &lt;b&gt;drive&lt;/b&gt;  в Main thread, что делает его идеальным для UI&lt;/li&gt;
&lt;li&gt;Описывать обработку ошибок внутри, не передавая ошибку по цепочке.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;...
asDriver()
       .drive({ value in 
       }) 
 ...&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Mon, 18 Nov 2019 08:20:36 +0300</pubDate></item><item><title>Итерация по enum</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/iteraciya-po-enum/</guid><link>https://blog.adeveloper.ru/all/iteraciya-po-enum/</link><description>&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;enum State {
    case none
    case one
    case two
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Конформим &lt;b&gt;State&lt;/b&gt; под протокол &lt;b&gt;CaseIterable&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;extension State: CaseIterable {}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;После этого мы можем итерироваться&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;State.allCases.forEach {
    print($0)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Wed, 06 Nov 2019 19:49:21 +0300</pubDate></item><item><title>Интересные Callback'и</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/interesnye-callbacki/</guid><link>https://blog.adeveloper.ru/all/interesnye-callbacki/</link><description>&lt;p&gt;Объявляем тип для callback замыкания&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;typealias RegStateCallbackType = @convention(c) (_ accountId: pjsua_acc_id) -&amp;gt; Void&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;var onRegStateCallback: RegStateCallbackType?&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;И можно тогда заюзать следующим образом&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;endpointCfg.cb.on_reg_state = onRegStateCallback&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Tue, 13 Aug 2019 21:41:28 +0300</pubDate></item><item><title>Swift String to C char *</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/swift-string-to-char/</guid><link>https://blog.adeveloper.ru/all/swift-string-to-char/</link><description>&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;void mi_connect_device(char *device_name);&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;func connect(to device: String) {
        device.withCString {
            let int8Pointer = UnsafeMutablePointer&amp;lt;Int8&amp;gt;(mutating: $0)
            mi_connect_device(int8Pointer)
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Fri, 14 Jun 2019 00:51:43 +0300</pubDate></item><item><title>Время сборки в Xcode</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/vremya-sborki-v-xcode/</guid><link>https://blog.adeveloper.ru/all/vremya-sborki-v-xcode/</link><description>&lt;p&gt;Хочу видеть время сборки проекта&lt;/p&gt;
&lt;h2&gt;Вариант 1:&lt;/h2&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h2&gt;Вариант 2:&lt;/h2&gt;
&lt;p&gt;в папке с проектом выполнить в консоле комманду&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;time xcodebuild&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Запуск из консоли&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;xcodebuild -workspace CallKitExample.xcworkspace -scheme CallKitExample -showBuildTimingSummary&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Sat, 01 Jun 2019 16:19:57 +0300</pubDate></item><item><title>RxSwift кастомная View'ха</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/rxswift-kastomnaya-viewha/</guid><link>https://blog.adeveloper.ru/all/rxswift-kastomnaya-viewha/</link><description>&lt;p&gt;Пишем своё расширение кастомной вьюхи.&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import UIKit
import RxSwift
import RxCocoa


class CustomControl: UIControl {
    
    var value: Int = 0 {
        didSet { sendActions(for: .valueChanged)}
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
    }
    
    func toggle() {
        if value == 0 {
            backgroundColor = .green
            value = 1
        } else {
            backgroundColor = .red
            value = 0
        }
    }
    
}

extension Reactive where Base: CustomControl {
    var value: ControlProperty&amp;lt;Int&amp;gt; {
        return base.rx.controlProperty(editingEvents: UIControlEvents.valueChanged, getter: { customView in
            return customView.value
        }, setter: { customView, newValue in
            customView.value = newValue
        })
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;И теперь использовать можно так&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;customView.rx.value
            .subscribe(onNext: { value in
                print(&amp;quot;changed my value -&amp;gt; \(value)&amp;quot;)
            })
            .disposed(by: bag)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;pre&gt;

&lt;/pre&gt;
</description><pubDate>Thu, 07 Mar 2019 04:03:09 +0300</pubDate></item><item><title>Login screen</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/login-screen/</guid><link>https://blog.adeveloper.ru/all/login-screen/</link><description>&lt;p&gt;Реализовал Login screen на VIPER, хотя в несколько облегчённом варианте, скорее всего ещё допилю взаимодействие между модулями. Router — &gt; Router + Presenter&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://blog.adeveloper.ru/pictures/Splash.png" width="320" height="693" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/adevelopers/LoginOnVIPER"&gt;Мои исходники&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;VIPER&lt;br /&gt;
V — View (Views + ViewControllers)&lt;br /&gt;
I — Interactor — бизнес логика модуля&lt;br /&gt;
P — Presentor (ViewModels and prepare)&lt;br /&gt;
E — Entities — (Models)&lt;br /&gt;
R — Router&lt;/p&gt;
</description><pubDate>Fri, 01 Mar 2019 15:03:36 +0300</pubDate></item><item><title>Обновил вид диаграммера</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/obnovil-vid-diagrammera/</guid><link>https://blog.adeveloper.ru/all/obnovil-vid-diagrammera/</link><description>&lt;div class="e2-text-picture"&gt;
&lt;a href="https://blog.adeveloper.ru/pictures/MainScreen.png" class="e2-text-picture-zoom-link" width="1024"&gt;
&lt;div class="e2-text-picture-zoom-icon"&gt;&lt;div class="e2-text-picture-zoomable"&gt;&lt;/div&gt;&lt;div class="e2-text-picture-zoom-in"&gt;&lt;/div&gt;&lt;/div&gt;
&lt;img src="https://blog.adeveloper.ru/?go=@scale-image:MainScreen.png" width="768" height="576" alt="" /&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Изменил вид PopupColorPickerView&lt;/p&gt;
</description><pubDate>Sun, 24 Feb 2019 20:26:38 +0300</pubDate></item><item><title>Следующие слова из статьи с New York Times</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/money/</guid><link>https://blog.adeveloper.ru/all/money/</link><description>&lt;h3&gt;Слова:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;along — вместе&lt;/li&gt;
&lt;li&gt;being — являющийся&lt;/li&gt;
&lt;li&gt;accused — обвиняемый&lt;/li&gt;
&lt;li&gt;whistling —  свистящий&lt;/li&gt;
&lt;li&gt;kindle — зажигать&lt;/li&gt;
&lt;li&gt;crumbling — рушиться&lt;/li&gt;
&lt;li&gt;wither — увядать&lt;/li&gt;
&lt;li&gt;apart — кроме&lt;/li&gt;
&lt;li&gt;neglected — пренебрегли&lt;/li&gt;
&lt;li&gt;slaughter — забой скота&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://www.nytimes.com/interactive/2019/02/20/us/emmett-till-murder-legacy.html?action=click&amp;module=Top%20Stories&amp;pgtype=Homepage"&gt;Источник&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Sat, 23 Feb 2019 00:26:36 +0300</pubDate></item><item><title>Мои попытки учить английский самостоятельно.</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/moi-popytki-uchit-angliyskiy-samostoyatelno/</guid><link>https://blog.adeveloper.ru/all/moi-popytki-uchit-angliyskiy-samostoyatelno/</link><description>&lt;p&gt;Переодически говорю себе, что мне нужен английский. хотя кроме потребности иногда что-то прочитать профессионального по работе, казалось бы жесткой необходимости знать английский и нет.&lt;br /&gt;
Хотелось бы проходить собеседование на английском, говорить в кафе как нейтив.&lt;/p&gt;
&lt;p&gt;Попробую каждый день читать быстро 5-10 минут по статье из &lt;a href="https://www.nytimes.com/"&gt;New York Times&lt;/a&gt; или &lt;a href="https://www.thetimes.co.uk/"&gt;The Times&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Взял &lt;a href="https://www.nytimes.com/2019/02/21/business/china-xinjiang-uighur-dna-thermo-fisher.html?action=click&amp;module=Top%20Stories&amp;pgtype=Homepage"&gt;статью&lt;/a&gt;.&lt;br /&gt;
Решил выписывать неизвестные обороты из неё.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;They &lt;b&gt;drew&lt;/b&gt; blood from him&lt;br /&gt;
Они &lt;b&gt;вытянули&lt;/b&gt; кровь из него&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;caught&lt;/b&gt; up in a vast Chinese campaign of surveillance and oppression.&lt;br /&gt;
&lt;b&gt;втянутый&lt;/b&gt; в обширную китайскую кампанию слежки и угнетения.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Посмотрим смогу ли я продержаться хотя бы неделю.&lt;/p&gt;
&lt;p&gt;Оказалось что статья это много для 5 минут, учитывая что и сюда надо оформить пару строк, думаю стоит тогда брать пару абзацев. Возможно дойду до того что буду выписывать основные мысли статей.&lt;/p&gt;
&lt;p&gt;Список слов:&lt;br /&gt;
Dreamy day —  мечтательные дни&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://blog.adeveloper.ru/pictures/resort_thai_beach.jpg" width="685" height="385" alt="" /&gt;
&lt;/div&gt;
</description><pubDate>Fri, 22 Feb 2019 01:00:18 +0300</pubDate></item><item><title>Swift KVO</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/swift-kvo/</guid><link>https://blog.adeveloper.ru/all/swift-kvo/</link><description>&lt;p&gt;Модель&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import Foundation

@objc class Card: NSObject {
    
    @objc dynamic var life: Int = 0
    @objc dynamic var atack: Int = 0
    @objc dynamic var defense: Int = 0
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Задаём переменную для invalidate()&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;var cardObserver: NSKeyValueObservation?&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Подписываемся на изменения и вешаем обработчик&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;let card = Card()
        cardObserver = card.observe(\Card.life, options: .old, changeHandler: { card, change in
            print(&amp;quot;Changed life value \(card.life) -&amp;gt; &amp;quot;, change.oldValue ?? -1)
        })&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Соответсвенно когда мы меняем значение переменной `life` то вызывается наш обработчик&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;card.life = 12
card.life = 1
card.life = 34&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Mon, 21 Jan 2019 23:25:57 +0300</pubDate></item><item><title>Swift: setTimeOut</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/swift-settimeout/</guid><link>https://blog.adeveloper.ru/all/swift-settimeout/</link><description>&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;DispatchQueue.main.asyncAfter(deadline: .now() + 0.600) {
     // some code
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Sun, 13 Jan 2019 01:52:40 +0300</pubDate></item><item><title>RxSwift: создаём реактивное расширение</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/rxswift-sozdayom-reaktivnoe-rasshirenie/</guid><link>https://blog.adeveloper.ru/all/rxswift-sozdayom-reaktivnoe-rasshirenie/</link><description>&lt;h2&gt;Расширение&lt;/h2&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;extension Reactive where Base: NSView {
    
    public var alphaValue: ControlProperty&amp;lt;CGFloat&amp;gt; {
        
        let source = self.observeWeakly(CGFloat.self, &amp;quot;alphaValue&amp;quot;, options: [.initial, .new])
            .filter { $0 != nil }.map { $0! }
            .takeUntil(deallocated)
        
        let observer = Binder&amp;lt;CGFloat&amp;gt;(base) { control, value in
            control.alphaValue = value
        }
        
        return ControlProperty(values: source, valueSink: observer)
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h2&gt;Применение&lt;/h2&gt;
&lt;h3&gt;подписываемся на изменения переменной&lt;/h3&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;view.rx.alphaValue.subscribe(onNext: { value in
                print(&amp;quot;val-&amp;gt;&amp;quot;, value)
            })
            .disposed(by: disposeBag)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h3&gt;меняем значение по слайдеру&lt;/h3&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;slider.rx.value.subscribe({ [weak self] item in
                let newValue = Int( item.element  ?? 0 )
                self?.view.alphaValue = newValue
            })
         .disposed(by: disposeBag)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Sat, 12 Jan 2019 13:34:17 +0300</pubDate></item><item><title>RxSwift: Создание реактивной переменной</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/rxswift-sozdanie-reaktivnoy-peremennoy/</guid><link>https://blog.adeveloper.ru/all/rxswift-sozdanie-reaktivnoy-peremennoy/</link><description>&lt;p&gt;Код должен быть прозрачным&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;import RxSwift&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h2&gt;Способ 1&lt;/h2&gt;
&lt;p&gt;Создаём переменную&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;var hitPoints = Variable&amp;lt;Int&amp;gt;(10)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Изменение значение переменной&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;card.hitPoints.value = hp&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Подписка на изменение&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;card.hitPoints.asObservable().subscribe(onNext: { [weak self] value in
            print(&amp;quot;Your hit points -&amp;gt;&amp;quot;, value)
            self?.labelHitPoints.stringValue = &amp;quot;\(value)&amp;quot;
        })
            .disposed(by: bag)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h2&gt;Способ 2&lt;/h2&gt;
&lt;p&gt;Создаём переменную&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;var rxMana = BehaviorRelay&amp;lt;Int&amp;gt;(value: 0)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Вешаем обработчик на реактивную переменную&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;self.rxMana.subscribe(onNext: { value in
            print(&amp;quot;Your level mana -&amp;gt;&amp;quot;, value)
        })
            .disposed(by: disposeBag)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Ну и где-нить меняем значение переменной&lt;/p&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;rxMana.accept(newValue)&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Sat, 12 Jan 2019 13:22:57 +0300</pubDate></item><item><title>Как передать в vue filter контекст компоненты</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/kak-peredat-v-vue-filter-kontekst-komponenty/</guid><link>https://blog.adeveloper.ru/all/kak-peredat-v-vue-filter-kontekst-komponenty/</link><description>&lt;h2&gt;Задача&lt;/h2&gt;
&lt;p&gt;Во &lt;b&gt;vue&lt;/b&gt; фильтры являются чистыми функциями и они ничего не знают об окружении из которого вызываются, а обратиться к данным компоненты из них бывает очень полезно, а иногда просто жизненно необходимо.&lt;/p&gt;
&lt;h2&gt;Решение&lt;/h2&gt;
&lt;h3&gt;в шаблоне компоненты&lt;/h3&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;:value=&amp;quot;value | filterNumber(this)&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;h3&gt;в компоненте&lt;/h3&gt;
&lt;pre&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;...
    filters: {
              filterNumber: function(value, self) {
                  console.log(&amp;quot;this-&amp;gt;&amp;quot;, self.propName)
                  return value;
              }
            },
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;/pre&gt;
</description><pubDate>Wed, 14 Nov 2018 20:01:59 +0300</pubDate></item><item><title>UX design</title><guid isPermaLink="true">https://blog.adeveloper.ru/all/ux-design/</guid><link>https://blog.adeveloper.ru/all/ux-design/</link><description>&lt;blockquote&gt;
&lt;p&gt;Один из основных навыков UX-дизайнера — это умение рассказывать о сложных вещах простыми словами.&lt;br /&gt;
Делая UX простым, вы сможете влиять на окружающих.&lt;/p&gt;
&lt;/blockquote&gt;
</description><pubDate>Tue, 25 Sep 2018 13:05:19 +0300</pubDate></item>
</channel>

</rss>