Developing a Mobile App for Home Rental (Airbnb Clone)
A home rental platform is a two-sided app (guest + host) with a marketplace, escrow payment system, built-in chat, and trust infrastructure. Complexity lies not in individual features but in the fact that both guest and host must simultaneously trust the platform with money and property. This determines architecture from payment storage to identity verification.
One App or Two with Role Switching
First approach: one app with "guest" and "host" modes, or two separate apps. Airbnb uses one app. In practice, one is easier to maintain, but host screens (managing listings, calendar blocked dates, payouts) differ significantly from guest screens. On iOS—switching via TabView with different tab sets based on active role. On Android—BottomNavigationView with dynamic menu items.
Listing: Data Structure and Photos
A listing is the richest object in the system:
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, // instant booking or request
val photos: List<String>, // URLs in CDN
val avgRating: Float?,
val reviewCount: Int
)
Photo upload from host—via UIImagePickerController / PHPickerViewController (iOS) or PhotoPicker API (Android 13+). Compress photos before upload: UIGraphicsImageRenderer on iOS, Bitmap.compress() on Android. Full resolution not needed—1200px on long side is sufficient. Upload to S3 / Cloudflare R2 via presigned URL to avoid binary data through your server.
Calendar and Availability
Host marks blocked dates and sets price by day of week (Friday/Saturday more expensive). Guest sees available ranges. Custom CalendarView—no standard component supports multi-day range selection with occupied date coloring.
On iOS: UICollectionView with custom UICollectionViewFlowLayout—day cells, selected range highlighting. On Android: use kizitonwose/calendar-compose—quality library with range selection and decorators.
// SwiftUI: custom 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) }
}
}
}
}
Payment System with Escrow
Guest funds should not go directly to host—this is escrow. Airbnb holds funds for 24 hours after check-in, then releases to host. Scheme:
- Guest books → funds deducted from card and frozen on platform account
- Check-in occurred → after 24 hours, funds unlock and go to host
- Issue at check-in → funds return to guest
Implemented via YooKassa or Stripe Connect. Stripe Connect is most flexible: destination charge or separate charge and transfer. Host registers Connected Account; payout—POST /v1/transfers with destination (host account). Cancellation—POST /v1/refunds.
For Russian market: YooKassa with POST /v3/payouts for host payouts, requires split payment connection.
Chat Between Guest and Host
Built-in chat is mandatory. Firebase Realtime Database or Stream Chat (ready SDK for iOS/Android with UI). Stream Chat faster to integrate: StreamChatClient, ChatChannelView—ChannelList and MessageList out-of-the-box, image support, typing indicator.
Important: conversations must be stored on platform. Don't allow contact sharing before booking—platform loses transaction and trust.
Verification and Trust
Identity Verification: passport photo via VisionKit / ML Kit Document Scanner + selfie with liveness detection. Integrate Sum Sub or Veriff—their mobile SDK handles entire verification flow.
Property Verification: host confirms address. Send physical letter with code (rare) or verify via government services API (ESIA OAuth).
Ratings: two-way reviews—guest rates property, host rates guest. Both see rating only after both leave reviews (blind review)—reduces bias.
Search and Map
PostGIS for geosearch with filters (property type, rooms, amenities, price). Search by polygon—user moves map, results update for visible area (GET /listings?bounds=lat1,lon1,lat2,lon2). Marker clustering.
Full-text search by city via Mapbox Geocoding API or Nominatim (OpenStreetMap)—convert text to coordinates before geosearch.
Stages and Timeline
| Stage | Timeline |
|---|---|
| Architecture: roles, data models | 1 week |
| Listing: creation, photos, calendar | 2 weeks |
| Search, map, filters | 2 weeks |
| Booking, escrow, payment | 2 weeks |
| Chat, notifications | 1 week |
| Verification, reviews, profiles | 1 week |
| Testing, build | 1 week |
Total: 10–14 weeks for complete MVP of both roles. Pricing is calculated individually after requirements analysis.







