Разработка мобильного приложения для аренды жилья (аналог Airbnb)
Платформа аренды жилья — это двухстороннее приложение (гость + хозяин) с маркетплейсом, escrow-платёжной системой, встроенным чатом и доверительной инфраструктурой. Сложность не в отдельных фичах, а в том, что гость и хозяин должны одновременно доверять платформе деньги и недвижимость. Это определяет архитектуру от хранения платежей до системы идентификации.
Двойное приложение или одно с переключением ролей
Первое решение: одно приложение с режимами «гость» / «хозяин» или два отдельных приложения. Airbnb использует одно приложение. На практике — одно проще поддерживать, но экраны хозяина (управление листингами, calendar blocked dates, выплаты) сильно отличаются от экранов гостя. На iOS — переключение через TabView с разными наборами вкладок в зависимости от активной роли. На Android — BottomNavigationView с динамическим набором пунктов.
Листинг жилья: структура данных и фотографии
Листинг — самый богатый объект в системе:
data class Listing(
val id: String,
val hostId: String,
val title: String,
val description: String,
val propertyType: PropertyType, // APARTMENT, HOUSE, ROOM, VILLA
val location: GeoPoint,
val address: Address,
val roomCount: Int,
val maxGuests: Int,
val amenities: Set<Amenity>, // WIFI, KITCHEN, PARKING, POOL...
val rules: HouseRules,
val pricePerNight: Decimal,
val cleaningFee: Decimal,
val minNights: Int,
val instantBook: Boolean, // мгновенное бронирование или запрос
val photos: List<String>, // URLs в CDN
val avgRating: Float?,
val reviewCount: Int
)
Загрузка фотографий от хозяина — через UIImagePickerController / PHPickerViewController (iOS) или PhotoPicker API (Android 13+). Фото сжимаем перед загрузкой: UIGraphicsImageRenderer на iOS, Bitmap.compress() на Android. Оригинал не нужен — достаточно 1200px по длинной стороне. Загружаем в S3 / Cloudflare R2 через presigned URL, чтобы бинарные данные не шли через ваш сервер.
Календарь и availability
Хозяин отмечает заблокированные даты и настраивает цену по дням недели (пятница/суббота дороже). Гость видит доступные диапазоны. Это кастомный CalendarView — ни один стандартный компонент не поддерживает многодневный range selection с раскраской занятых дат.
На iOS: UICollectionView с кастомным UICollectionViewFlowLayout — ячейки дня, подсветка выбранного диапазона. На Android: можно взять kizitonwose/calendar-compose — качественная библиотека с поддержкой range selection и декораторов.
// SwiftUI: кастомный range calendar
struct RangeCalendarView: View {
@Binding var checkIn: Date?
@Binding var checkOut: Date?
let blockedDates: Set<DateComponents>
let pricedDates: [DateComponents: Decimal]
var body: some View {
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 7)) {
ForEach(calendarDays, id: \.self) { day in
DayCell(
date: day,
isBlocked: blockedDates.contains(day.dateComponents),
price: pricedDates[day.dateComponents],
isInRange: isInSelectedRange(day),
isCheckIn: day.date == checkIn,
isCheckOut: day.date == checkOut
)
.onTapGesture { handleDayTap(day) }
}
}
}
}
Платёжная система с escrow
Деньги гостя не должны сразу уходить хозяину — это escrow. Airbnb держит деньги до 24 часов после заезда, потом переводит хозяину. Схема:
- Гость бронирует → деньги списываются с карты и замораживаются на счёте платформы
- Check-in наступил → через 24 часа деньги разблокируются и идут хозяину
- Проблема при заезде → деньги возвращаются гостю
Реализуется через ЮKassa или Stripe Connect. Stripe Connect — наиболее гибкий: destination charge или separate charge and transfer. Хозяин регистрирует Connected Account; выплата — POST /v1/transfers с указанием destination (счёт хозяина). Отмена — POST /v1/refunds.
Для российского рынка: ЮKassa с POST /v3/payouts для выплат хозяевам, требует подключения сплит-оплаты.
Чат между гостем и хозяином
Встроенный чат — обязательный элемент. Firebase Realtime Database или Stream Chat (готовый SDK для iOS/Android с UI). Stream Chat быстрее в интеграции: StreamChatClient, ChatChannelView — ChannelList и MessageList из коробки, поддержка изображений, индикатор печати.
Важно: переписка должна храниться на платформе. Не разрешать делиться контактами до бронирования — платформа теряет транзакцию и доверие к безопасности.
Верификация и доверие
Верификация личности: фото паспорта через VisionKit / ML Kit Document Scanner + selfie с liveness detection. Интегрируем Sum Sub или Veriff — их мобильный SDK обрабатывает весь flow верификации.
Верификация жилья: хозяин должен подтвердить адрес. Отправляем физическое письмо с кодом (редко) или верифицируем через госуслуги API (ЕСИА OAuth).
Рейтинги: двусторонние отзывы — гость оценивает жильё, хозяин оценивает гостя. Оба видят оценку только после того, как оба оставили отзыв (blind review) — снижает предвзятость.
Поиск и карта
PostGIS для геопоиска с фильтрами (тип жилья, количество комнат, удобства, цена). Поиск по полигону — пользователь двигает карту, результаты обновляются по видимой области (GET /listings?bounds=lat1,lon1,lat2,lon2). Кластеризация маркеров.
Полнотекстовый поиск по городу через Mapbox Geocoding API или Nominatim (OpenStreetMap) — конвертируем текст в координаты перед геопоиском.
Этапы и сроки
| Этап | Срок |
|---|---|
| Архитектура: роли, модели данных | 1 неделя |
| Листинг: создание, фото, calendar | 2 недели |
| Поиск, карта, фильтры | 2 недели |
| Бронирование, escrow, оплата | 2 недели |
| Чат, уведомления | 1 неделя |
| Верификация, отзывы, профили | 1 неделя |
| Тестирование, сборка | 1 неделя |
Итого: 10–14 недель для полноценного MVP обеих ролей. Стоимость рассчитывается индивидуально после анализа требований.







