Converleon — офлайн-конвертер для macOS, выпущенный в Mac App Store. Он работает с изображениями, видео, аудио, документами, PDF и архивами, в том числе когда пользователь передаёт несколько файлов разных типов одновременно. Вместо обычного окна приложение показывает компактный баббл рядом с местом, куда были перетащены файлы.
Продукт: сайт Converleon · Mac App Store
Публичный engineering showcase. Репозиторий содержит самостоятельно запускаемое Swift-ядро реального коммерческого macOS-приложения, выпущенного в App Store. Полный продукт также включает специализированные конвертеры, баббл-интерфейс на SwiftUI и AppKit, App Sandbox, StoreKit, onboarding, 18 локализаций и систему выпуска обновлений, которые не публикуются.
Демонстрация показывает работу с основными типами файлов: изображениями, видео, аудио, документами и архивами. Актуальная версия также поддерживает улучшение изображений, удаление фона, сжатие и дополнительные форматы.
Несколько типов файлов, один способ взаимодействия и результат рядом с исходником. Нажмите, чтобы увеличить.
Converleon объединяет повседневные задачи с файлами в одном локальном приложении:
- конвертирует смешанные наборы изображений, видео, аудио, документов, PDF и архивов;
- сжимает медиафайлы, извлекает аудио, улучшает изображения и удаляет фон;
- объединяет и разделяет PDF, создаёт многостраничные документы;
- распаковывает распространённые форматы архивов и упаковывает любые файлы и папки в ZIP;
- выполняет операции полностью локально — файлы не загружаются на сервер конвертации;
- сохраняет результат рядом с исходниками, оставляя оригиналы неизменными.
Приложение доступно во всех странах Mac App Store. Страница продукта и снимки экрана локализованы на 18 языков. Встроенные покупки работают на StoreKit 2: пользователю доступны семидневный пробный период со всеми функциями, месячная и годовая подписки, а также бессрочная покупка.
Страница Converleon в App Store Connect на примере японской и арабской локализаций.
Рабочий интерфейс Converleon — прозрачная безрамочная панель NSPanel, которая появляется рядом с точкой перетаскивания. Пользователь остаётся в контексте Finder и видит только действия, доступные для выбранных файлов.
flowchart TB
F["Файлы в Finder"] -->|"1. Перетащить"| I["Иконка Converleon"]
I --> B["Контекстный баббл рядом с курсором"]
B -->|"2. Выбор действия"| C["Локальная конвертация"]
C --> R["Результат рядом с исходниками"]
Один визуальный объект переключается между режимами:
- форматы;
- варианты сжатия;
- запрос пароля для защищённых архивов;
- подписка и экран оплаты;
- справка, лицензии и поддержка;
- сведения о конвертации и типизированные ошибки.
Один баббл объединяет выбор формата, справку, подписку и рабочие состояния.
Баббл сохраняет пространственную связь с исходным действием и при этом остаётся полностью видимым при любом положении иконки приложения. Алгоритм автоматически выбирает один из четырёх вариантов панели: выше или ниже, левее или правее точки перетаскивания. Баббл раскрывается в сторону свободной области, не уходя за границы экрана. Ход операции и финальная галочка отображаются отдельной анимацией в той же точке.
Кнопки выходных форматов расположены в два столбца. Когда доступных действий нечётное количество, в последней строке остаётся пустая ячейка. Converleon превращает её в узнаваемую деталь интерфейса: свободное место занимает хамелеон — талисман продукта. У него нет рамки или отдельной кнопки, словно он просто поселился внутри баббла.
Его глаза следят за курсором по всему экрану. При клике хамелеон исчезает, визуально сливаясь с фоном, а при следующем подходящем состоянии баббла может появиться снова.
Название связывает функцию приложения с образом бренда: хамелеон меняет окраску, а Converleon — формат файла. Эта деталь одновременно:
- балансирует нечётную сетку форматов;
- оживляет минималистичный интерфейс;
- добавляет ненавязчивую интерактивную пасхалку;
- без слов раскрывает название Converleon = converter + chameleon.
Так особенность сетки становится не компромиссом, а частью визуального языка и характера продукта.
Основной повторяемый сценарий:
- Перетащить один или несколько файлов на иконку приложения Converleon.
- Выбрать в появившемся баббле формат или действие.
Также поддерживаются команда Open With («Открыть с помощью»), системное открытие файла приложением, File → Convert Files… и ⌘O. Для набора файлов разных типов баббл показывает только подходящие действия, поэтому пользователю не приходится проходить отдельные экраны выбора исходного и выходного форматов.
Converleon не требует предварительно открывать приложение, выбирать файлы в главном окне и отдельно задавать место сохранения. Рабочий сценарий начинается непосредственно с файлов и сокращается до двух действий: перетаскивания на иконку и выбора операции в контекстном баббле. Пользователь остаётся в Finder, а результат появляется рядом с исходниками.
Отказ от обычного главного окна — основа продуктовой концепции, а не только визуальное решение. Такое устройство убирает промежуточные экраны и клики из повторяемого сценария конвертации. При обычном запуске Converleon открывается отдельное плавающее окно с коротким зацикленным видео: пользователь может познакомиться с механикой или быстро освежить её в памяти. Видео показывает основной сценарий перетаскивания, команду Open With и добавление приложения на панель инструментов Finder.
Видео знакомит с нестандартной моделью взаимодействия при обычном запуске приложения.
Если приложение получает один или несколько файлов — при перетаскивании на иконку, через Open With или другое системное событие открытия, — обучающее видео не показывается. Converleon сразу открывает баббл с доступными действиями. Drag-and-drop остаётся основным сценарием, а Open With — дополнительным системным способом передать файл.
Окно обучения собрано на SwiftUI, AVQueuePlayer и AVPlayerLooper внутри отдельного NSWindow.
Работа над Converleon охватывала продуктовую концепцию, пользовательский опыт и дизайн, архитектуру приложения и системы конвертации, тестирование, подготовку 18 локализаций и выпуск в App Store.
Ключевые области ответственности:
- двухшаговая модель взаимодействия и пространственный баббл-интерфейс с адаптивным позиционированием;
- хамелеон-талисман как сочетание логики сетки, микровзаимодействия и образа бренда;
- жизненный цикл окон на SwiftUI и AppKit;
- конвейер конвертации для нескольких классов файлов;
- App Sandbox и минимально необходимый доступ к файлам;
- StoreKit 2, пробный период, подписки и бессрочная покупка;
- понятные состояния ошибок и предсказуемое сохранение результата;
- выпуск в App Store, материалы ASO и 18 локализаций.
SwiftUI отвечает за представления, AppKit — за жизненный цикл окон, NSPanel, NSWindow, NSHostingView, активацию и фокус. Системное отслеживание мыши фиксирует точку отпускания файлов и позволяет хамелеону следить за курсором по всему экрану.
Координаты этой точки используются не только для привязки интерфейса к действию пользователя. Алгоритм рассчитывает расстояние до диагоналей видимой области экрана, определяет направление с наибольшим запасом пространства и выбирает одну из четырёх конфигураций KeyPanel: выше или ниже, левее или правее иконки. Панель без рамки раскрывается в выбранном направлении, поэтому баббл целиком остаётся на экране даже тогда, когда иконка Converleon находится у его края или в углу. При необходимости панель получает фокус клавиатуры.
Приложение использует разрешение user-selected.read-write и закладки ограниченного доступа. Если прав недостаточно, пользователь выбирает исходную папку через NSOpenPanel. Converleon получает доступ только к нужному расположению и сохраняет результат рядом с исходным файлом.
StoreKit встроен в тот же баббл. Тарифы Monthly, Yearly и Lifetime, восстановление покупок, промокод и управление подпиской не требуют отдельного окна или другого языка интерфейса.
Репозиторий показывает архитектурное ядро конвертации и транзакционный жизненный цикл файловой операции:
- определение типа входного файла;
- получение допустимых форматов из определённого типа и реестра стратегий;
- выбор реализации через
ConversionStrategy; - резервирование уникального URL результата;
- запись во временную область;
- атомарное перемещение готового файла;
- очистка временных артефактов;
- возврат типизированного результата или ошибки вызывающему интерфейсу.
Код демонстрирует:
- паттерн
Strategy: конвертеры реализуют единый протоколConversionStrategy; - централизованное определение типа через соответствие
UTType; - формирование списка доступных действий из возможностей стратегий, а не из отдельного списка в интерфейсе;
- резервирование имени результата в отдельном акторе;
- защиту от перезаписи и конкурентных конфликтов;
- временную область на том же томе файловой системы;
- управление асинхронным процессом через structured concurrency и actor isolation;
- пакетное выполнение с ограниченной конкурентностью, сохранением входного порядка и изоляцией ошибки отдельного файла;
- централизованную очистку при ошибке и
CancellationError; - обнаружение внешнего конфликта между reservation и commit без перезаписи чужого файла;
- XCTest для успешного сценария, отмены, типизированных ошибок, атомарности и конкурентного выполнения.
Каждый формат реализует ConversionStrategy и объявляет поддерживаемые типы. Новый конвертер добавляется без изменения ConversionCoordinator и разрастания условной логики.
FileTypeDetector обрабатывает известные расширения, затем использует системный UTType и его граф соответствий. Координатор получает явный типизированный результат.
OutputURLAllocator реализован как actor. Параллельные задачи не получают одинаковый путь результата, даже пока итоговый файл ещё не создан; reservation освобождается и после успеха, и при ошибке или отмене.
Стратегия пишет в staging-файл в целевой директории, поэтому commit выполняется атомарным moveItem на том же томе. Перед commit координатор повторно проверяет зарезервированный URL: если его занял внешний процесс, чужой файл сохраняется, staging удаляется, а вызывающий код получает typed error.
входной URL
│
▼
FileTypeDetector ──► ConversionCoordinator ──► ConversionStrategy
│ │
▼ ▼
OutputURLAllocator временный файл
│ │
└──── атомарный перенос ◄─┘
- ConversionStrategy.swift — контракт расширения конвейера конвертации.
- ConversionCoordinator.swift — жизненный цикл операции.
- BatchConversion.swift — ограниченная конкурентность и результаты отдельных элементов пакета.
- OutputURLAllocator.swift — конкурентное резервирование имён.
- FileTypeDetector.swift — централизованное определение типа.
- ConversionCoordinatorTests.swift — атомарность, отмена, внешний конфликт и конкурентное выполнение.
Требуются macOS 13+ и Swift 6.0+.
swift run conversion-demoCLI выполняет сквозной файловый сценарий и позволяет проверить собираемость пакета, жизненный цикл конвертации и основные инварианты библиотечного ядра.
swift build
swift format lint --configuration .swift-format --recursive Sources Tests Package.swift
bash scripts/check-coverage.sh
bash scripts/check.shcheck-coverage.sh запускает тесты с инструментированием и требует не менее 85% покрытия строк библиотечного ядра. GitHub Actions повторяет полный набор проверок на macOS.
Публичный репозиторий сосредоточен на ядре конвертации и файловых сценариях, в которых особенно важны безопасность и предсказуемость результата. Полная версия из App Store дополняет его специализированными стратегиями для macOS, баббл-интерфейсом, разрешениями песочницы, StoreKit и системой выпуска обновлений.
Натали Антро — AI Product Engineer, создатель и единственный разработчик продукта.