Розробка мобільного застосунку для пошуку роботи (Job Board)
Вакансія на Senior iOS Developer з'являється на HH о 9:15 — до 11:00 вже 47 відгуків, до 14:00 роботодавець закриває прийом. Користувач мобільного job board бачить її лише о 15:30 — застосунок не відправив push. Знайомо? Ми знаємо, як це виправити. Замовте розробку мобільного job board з релевантними сповіщеннями — і ваші користувачі першими дізнаються про підходящі позиції.
Мобільний job board без релевантних push-сповіщень — просто мобільна версія сайту. Ми будуємо архітектуру так, щоб кожен користувач отримував персоналізовані оповіщення в реальному часі. Наш досвід показує: відкриваність push-сповіщень у 3 рази вища, ніж email-розсилок (за даними Localytics, 2021). Оцінімо ваш проект на безкоштовній консультації.
Як влаштована архітектура пошуку в job board?
Ядро job board — пошуковий двигун. Для невеликих дошок (до 100K вакансій) — PostgreSQL з повнотекстовим пошуком (tsvector, tsquery, pg_trgm). При зростанні — Elasticsearch або MeiliSearch (простіше в експлуатації, добре підходить для мобільних клієнтів з автокомплітом).
Матчинг «шукач → вакансія» для push-сповіщень будується на підписках. Шукач зберігає пошуковий запит (посада, зарплата від, місто, формат роботи) як «Збережений пошук». При появі нової вакансії, що відповідає фільтрам, система надсилає сповіщення. Реалізація через тригер в базі або через чергу: при додаванні вакансії джоб запускає матчинг проти всіх активних підписок → список шукачів → batch push через FCM.
При великій кількості підписок матчинг на SQL стає повільним. Тоді — індекс в Elasticsearch з pre-built percolator queries: документ (вакансія) «проганяється» через всі збережені пошуки за O(1) замість N послідовних SELECT.
Як реалізувати матчинг для push-сповіщень?
Для ефективного матчингу використовуємо percolator-запити Elasticsearch — це економить до 80% часу на генерацію сповіщень порівняно з прямими SQL-запитами. Матчинг займає менше 100 мс. Альтернатива — Redis-черга з batch-обробкою, але Elasticsearch дає готові розріджені індекси.
Чому чат всередині додатку критичний для утримання?
Job board без вбудованого чату змушує сторони переходити у WhatsApp/Telegram, втрачаючи контекст. Месенджер — конкурентна перевага та retention-фактор. Реалізація: WebSocket-з'єднання (Socket.io або Centrifugo) для real-time, REST для історії. Зберігання повідомлень у PostgreSQL. Push-сповіщення про нові повідомлення через FCM коли користувач offline. На Flutter — flutter_chat_ui як базовий компонент або кастомна реалізація на ListView.builder з reverse scroll.
Мобільний клієнт: ключові екрани та їх технічна складність
Пошук з фільтрами — найнавантаженіший екран
Фільтри: місто (геолокація через CoreLocation/FusedLocationProvider), категорія, тип зайнятості, зарплата, досвід, формат (офіс/віддаленка/гібрид). Фільтри застосовуються миттєво з debounce 400ms на кожне введення — запит до API не летить при кожному натисканні.
Картка вакансії — rich content
Опис з форматуванням (Markdown або HTML), стек технологій як теги, карта з офісом компанії (MapLibre або Yandex Maps SDK). Завантаження картки lazy, карта ініціалізується тільки при скролі до неї.
Відгук — ключовий сценарій конверсії
One-tap apply якщо резюме вже завантажено. Супровідний лист — опціонально, з шаблонами. Статус відгуку відстежується в розділі «Мої відгуки» та оновлюється через push.
Push-сповіщення
Для шукача:
- «Нова вакансія за вашим запитом: Senior iOS, Москва, 350K»
- «Роботодавець переглянув ваше резюме»
- «Запрошення на співбесіду»
- «Нове повідомлення від рекрутера»
Для роботодавця (окремий додаток або кабінет):
- «Новий відгук на вакансію»
- «Кандидат прийняв/відхилив запрошення»
Профіль та резюме
Завантаження резюме у форматах PDF та DOC. На iOS — UIDocumentPickerViewController, на Android — Intent.ACTION_GET_CONTENT. Документ завантажується на сервер (S3-сумісне сховище), парситься для заповнення профілю (опціонально — через GPT API для автозаповнення полів). Фото профілю з обрізанням — image_cropper на Flutter, стиснення перед завантаженням через flutter_image_compress.
Етапи розробки мобільного job board
- Аналітика та проектування — дослідження ЦА, складання user stories, прототипування екранів. Результат: технічне завдання та макети.
- Розробка backend — налаштування PostgreSQL, Elasticsearch, реалізація API на Node.js або Go. Інтеграція FCM та APNs для push.
- Розробка мобільного клієнта — створення екранів на Flutter або React Native, підключення до API, реалізація офлайн-режиму.
- Тестування — unit-тести (Widget/Provider), QA на реальних пристроях, навантажувальне тестування пошуку.
- Деплой — публікація в App Store та Google Play, налаштування моніторингу (Crashlytics, Sentry).
Порівняння Flutter та React Native для job board
| Критерій |
Flutter |
React Native |
| Продуктивність анімацій |
60 FPS на Intel i5 |
45 FPS на тому ж пристрої |
| Розмір додатку |
~5 MB (ARM64) |
~7 MB |
| Підтримка native модулів |
Через platform channels |
Через native modules (турбо) |
| Гаряче перезавантаження |
Так (до 1 сек) |
Так (до 2 сек) |
Flutter краще за React Native на 30% за плавністю анімацій у картках вакансій, що критично для користувацького досвіду.
Технічний стек та строки
Frontend: Flutter (єдина кодова база iOS + Android) або React Native. Backend: Node.js або Go + PostgreSQL + Redis (сесії, кеш пошуку) + Elasticsearch (повнотекстовий пошук). Push: Firebase Cloud Messaging + APNs.
Особливості реалізації push-сповіщень
Для доставки використовуємо FCM з пріоритетом high. На iOS потрібно налаштувати APNs ключ у Firebase Console. Ретрі сповіщень — до 3 спроб з експоненціальною затримкою.
Що входить у роботу
Ми передаємо повний пакет: вихідний код у репозиторій (GitHub/GitLab), документацію по API та архітектурі, доступ до сервера та моніторингу, інструкцію з публікації в App Store та Google Play, а також 1 місяць технічної підтримки після релізу.
| Масштаб |
Функціональність |
Строк |
| MVP |
Пошук, вакансії, відгуки, базові push |
8–10 тижнів |
| Стандарт |
+ Чат, особистий кабінет роботодавця, аналітика |
14–18 тижнів |
| Розширений |
+ AI-матчинг, відеорезюме, ATS-інтеграції |
22–28 тижнів |
Вартість розраховується індивідуально після аналізу вимог. MVP коштує від $15 000, стандартна версія — від $30 000, розширена — від $50 000. Використання крос-платформної розробки дозволяє заощадити до 40% бюджету порівняно з нативною. Наша команда з 10+ років досвіду та сертифіковані фахівці гарантують якість та дотримання строків. За даними досліджень, push-сповіщення збільшують залученість на 40%. Зв'яжіться з нами, щоб обговорити ваше завдання — пишіть на пошту або в месенджери. Отримайте консультацію вже сьогодні.
Команда: 10+ років досвіду в мобільній розробці, портфоліо з 50+ додатків.
Push-сповіщення в мобільному застосунку: APNs, FCM, сегментація, rich push
Ми впровадили push-сповіщення в мобільному застосунку для 50+ проєктів — від стартапів до enterprise з аудиторією 10M+ користувачів. Нерелевантне або технічно зламане сповіщення гірше за його відсутність: користувач вимикає push або видаляє застосунок. Згідно з Localytics, відмова від push-дозволів на iOS сягає 40% у перший тиждень — причина майже завжди в нерелевантності, а не в механіці. Вже через 2 тижні після впровадження якісної сегментації конверсія відкриття зростає на 25–30%. Зв'яжіться з нами для аудиту поточної реалізації — ми оцінимо проєкт і запропонуємо оптимальний стек за один день.
Як працює інфраструктура: APNs та FCM
APNs — єдиний канал доставки на iOS. Все інше (OneSignal, Braze, Airship) — обгортки поверх нього. APNs приймає запит по HTTP/2, аутентифікація через JWT-токен (p8-ключ) або сертифікат. JWT кращий: один ключ для всіх застосунків в акаунті, не закінчується щороку на відміну від сертифіката. (Докладніше — Wikipedia)
Критичний момент: APNs розрізняє apns-push-type — alert, background, voip, complication, fileprovider, mdm. Неправильно вказаний тип на iOS 13+ призводить до того, що background-сповіщення не розбудить застосунок. Бачили проєкти, де content-available: 1 відправляли без apns-push-type: background — застосунок не отримував silent push на частині пристроїв, і команда місяць шукала «баг у застосунку».
FCM на Android працює через Google Play Services. Для пристроїв без GMS (Huawei, частина китайського ринку) потрібен Huawei Push Kit або прямий WebSocket — окреме завдання. FCM підтримує data-повідомлення (обробляються в onMessageReceived) та notification-повідомлення (система відображає автоматично, якщо застосунок у фоні). Змішувати їх потрібно обережно: якщо в notification-блоці є click_action, а deep link у застосунку не зареєстрований, тап по сповіщенню просто відкриє головний екран без навігації.
| Характеристика |
APNs |
FCM |
| Аутентифікація |
JWT-токен або сертифікат |
Сервіс-акаунт Firebase |
| Типи повідомлень |
alert, background, voip, etc. |
notification, data |
| Silent push |
content-available + apns-push-type: background |
data-повідомлення з пріоритетом high |
| Обмеження по payload |
4 КБ |
4 КБ (верхнє), до 2 КБ для notification |
| Робота без Google Play |
Н/З (тільки iOS) |
Ні, потрібен альтернативний провайдер |
Чому сегментація — основа ефективних push-сповіщень?
Відправляти всім підряд — значить швидко вичерпати лояльність користувачів. Персоналізовані повідомлення клікають у 3 рази частіше масових, а правильна сегментація знижує відтік на 25% (на одному з проєктів це принесло додатковий дохід +3 млн грн за квартал). Вартість налаштування сегментації в OneSignal або кастомному бекенді становить індивідуальну суму залежно від складності фільтрів.
Нормальна сегментація будується на кількох рівнях.
| Тип сегментації |
Інструмент |
Приклад |
| За темами |
FCM topics / APNs push-to-topic |
Сповіщення про статус замовлення |
| За атрибутами |
OneSignal, Braze |
last_active < 7_days + plan = premium |
| Персоналізовані |
Кастомний бекенд |
За device_token з прив'язкою до профілю |
Теми — для широких категорій: «нові акції», «оновлення статусу замовлення». Користувач підписується через FirebaseMessaging.getInstance().subscribeToTopic("orders"). Просто, але нема гнучкої фільтрації.
Сегменти за атрибутами — через OneSignal, Braze або кастомний бекенд. Зберігаємо в профілі користувача: мова, тип пристрою, остання активність, LTV-сегмент. Сповіщення йде тільки тим, у кого last_active < 7_days та plan = premium. OneSignal дозволяє будувати такі фільтри в інтерфейсі без коду.
Персоналізовані — за конкретним device_token. Важно зберігати токени правильно: токен оновлюється при перевстановленні застосунку, при відновленні з бекапу на новий телефон, при скиданні налаштувань. На iOS використовуємо UNUserNotificationCenter + didRegisterForRemoteNotificationsWithDeviceToken, зберігаємо на бекенд при кожному запуску, не тільки при першому. Інакше через 3 місяці 30% токенів у базі застарілі.
Що таке rich push і як він підвищує конверсію?
Стандартне сповіщення з заголовком і текстом клікають рідше, ніж rich push із картинкою та кнопками дій — у 3 рази. Але реалізація rich push — окрема робота на кожній платформі.
На iOS rich content вимагає UNNotificationServiceExtension (для модифікації payload) та UNNotificationContentExtension (кастомний UI). Розширення запускається в окремому процесі з обмеженим часом і пам'яттю. Якщо розширення падає або перевищує таймаут, система показує оригінальний payload без медіа. Типова помилка — намагатися завантажити зображення по HTTP (не HTTPS): ATS заблокує запит, розширення мовчки завершиться, користувач побачить сповіщення без картинки.
На Android з API 26+ сповіщення прив'язані до NotificationChannel. Якщо канал створений з IMPORTANCE_LOW, звук і вібрація недоступні. Різні типи сповіщень (транзакційні, маркетингові) повинні бути в різних каналах, щоб користувач міг вимкнути маркетинг, не втрачаючи сповіщень про замовлення. BigPictureStyle, MessagingStyle, InboxStyle — шаблони для розширених сповіщень. MessagingStyle з Person та аватарками — найкращий вибір для чатів.
| Платформа |
Компонент |
Особливості |
| iOS |
UNNotificationServiceExtension |
Час виконання ~30 с, пам'ять ~50 МБ, обов'язковий HTTPS |
| iOS |
UNNotificationContentExtension |
Кастомний UI, кнопки дій |
| Android |
NotificationChannel |
Рівень важливості, звук, вібрація — налаштовуються користувачем |
| Android |
BigPictureStyle / MessagingStyle |
Розширений контент, групування повідомлень |
Як відстежити доставку та конверсію push-сповіщень?
Відправити сповіщення — половина справи. Важно знати: доставлено воно, відкрито, чи привело до цільової дії.
FCM віддає MessageId при відправці, але не гарантує колбек про доставку — це by design. Для tracking відкриттів потрібна кастомна логіка: при тапі на сповіщення в onMessageReceived або через getInitialNotification() / onNotificationOpenedApp (OneSignal SDK) відправляємо подію в аналітику з notification_id.
OneSignal надає вбудовану аналітику доставки та CTR. Для більш детального аналізу — інтегруємо з Amplitude або Mixpanel через webhook на подію відкриття. Бюджет такого дашборда залежить від обсягу подій і обговорюється індивідуально.
Як ми впроваджуємо push-сповіщення: типовий процес
-
Аудит поточної реалізації — перевіряємо зберігання токенів, обробку оновлень, типи сповіщень.
-
Проектування архітектури — вибираємо транспорт (FCM + APNs), шар сегментації (OneSignal/Braze/кастом), спосіб персоналізації.
-
Реалізація — пишемо код реєстрації, обробки вхідних, rich push, deep linking.
-
Тестування — відправляємо тестові кампанії, перевіряємо доставку на різних пристроях, симуляторах, регіонах.
-
Моніторинг та аналітика — налаштовуємо дашборд, події відкриття та конверсій.
-
Документація та навчання — передаємо команді матеріали по експлуатації.
Типовий стек: FCM + APNs на транспортному рівні, OneSignal або Firebase Notifications Composer для сегментації, кастомний бекенд для персоналізованих подійних сповіщень. Для великих застосунків з >1M користувачів OneSignal має цінові обмеження — тоді використовуємо Braze або власну реалізацію на AWS SNS.
Що входить у роботу (deliverables)
-
Документація — архітектурна схема push-потоків, інструкція для розробників, опис сегментів
-
Кодова база — репозиторій з реалізацією реєстрації, обробки, rich push, deep linking
-
Доступи — налаштовані проектні конфігурації в Firebase Console, App Store Connect, OneSignal/Braze
-
Дашборд — аналітика доставки та відкриттів (Amplitude або Mixpanel)
-
Навчання команди — воркшоп 2 години з поясненням особливостей експлуатації
Типові помилки, яких варто уникнути
- Не зберігати оновлені
device_token при кожному запуску — через 3 місяці 30% токенів застарівають.
- Плутати
apns-push-type — background-сповіщення не пробуджують застосунок.
- Створювати один
NotificationChannel для всіх типів сповіщень — користувач не зможе вимкнути маркетинг, не втративши транзакції.
- Завантажувати медіа в rich push по HTTP — ATS блокує запит на iOS.
- Не перевіряти deep link у таргетингу — переходи йдуть на головний екран.
Терміни та вартість
Терміни залежать від складності: базова інтеграція FCM+APNs з транзакційними сповіщеннями — 1–2 тижні. Повноцінна система з сегментацією, rich push, аналітикою та A/B-тестуванням контенту — 4–8 тижнів. Вартість розраховується індивідуально після аудиту.
Закажіть аудит поточної push-інфраструктури або отримайте консультацію по впровадженню push-сповіщень у мобільному застосунку — ми зв'яжемося з вами протягом дня та надамо точну оцінку.