Developing a Mobile App for Real Estate (PropTech)
Real estate app aggregates property data, map search in visible area, filters with dozens of parameters, virtual tours, contact forms. Technically, the most painful part—not UI, but handling large property volumes on map and syncing filter state with search queries.
Map as Primary UI
Most PropTech app users search by map, not list. So map is first screen, not tab. This affects architecture: can't load all properties in single request—could be thousands.
Viewport-based loading—load only objects in current map visible area:
GET /properties?bounds=55.70,37.55,55.80,37.70&filters=...
bounds—viewport rectangle. On scroll/zoom—new request. Debounce 500 ms on onCameraIdle event (not onCameraMove)—request only after camera stops.
PostGIS on server:
SELECT id, lat, lon, price, property_type
FROM properties
WHERE geom && ST_MakeEnvelope(:west, :south, :east, :north, 4326)
AND price BETWEEN :min_price AND :max_price
ORDER BY created_at DESC
LIMIT 200;
Clustering. Many objects in area and low zoom—clusters with count inside. At zoom > 14—separate markers. iOS—GMUMarkerClusterer, Android—ClusterManager, Flutter—flutter_map_marker_cluster. Recalculate on every onCameraIdle.
Filters with Dozens of Parameters
Real estate filter—one of most complex UI components in mobile. Rooms, dwelling type, price range (Range Slider), area, floor, build year, contract type, urgency. Plus country-specific fields.
Main problem: filter state storage. Not in local screen variables—user leaves to property card and returns. Filter state should live in ViewModel / StateHolder and survive recomposition.
Android—data class FilterState in ViewModel, StateFlow<FilterState> in UI. On any filter field change—copy() + Flow update. Debounce 300 ms before API request—don't send on every slider drag.
filterState
.debounce(300)
.flatMapLatest { filters -> propertyRepository.search(filters) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
iOS—@Published var filterState: FilterState in ObservableObject, Combine.debounce(for:scheduler:).
Save search. User saves current filter set as "search agent"—gets push on new matching properties. FCM + server cron running saved queries hourly.
Property Card
Photo gallery with smooth scroll-driven transition from map. iOS—custom UIViewControllerTransitioningDelegate for hero animation marker → photo. Android—Shared Element Transition with ActivityOptionsCompat.makeSceneTransitionAnimation.
Virtual tour. 360° photo via VR Panorama or Matterport embed. iOS—SceneKit + spherical geometry for equirectangular panorama render, or WKWebView with Matterport iframe. Android—GoogleVR SDK (outdated but works) or WebView. Native render faster, WebView simpler with more formats.
Mortgage calculator. Simple client math—amount, rate, months → monthly payment. Annuity formula:
let monthlyRate = annualRate / 12 / 100
let n = Double(months)
let payment = principal * monthlyRate * pow(1 + monthlyRate, n) / (pow(1 + monthlyRate, n) - 1)
No API needed, works offline.
Data Source Integration
Real estate objects usually from multiple sources: parsing Cian/Avito (gray zone ToS-wise), own developer CRM, CREA/IDX feeds (Western markets), manual CMS entry.
For external portal aggregation—server sync via API (if available) or ETL pipeline. Invisible in mobile app—just normalized data from own API.
Developer with own CRM—REST API integration with field mapping. Sync via webhook (CRM notifies on object change) or schedule every 15 minutes.
iOS vs Android Specifics for PropTech
iOS 16+ has MapKit with MKMapView and SwiftUI integration. For PropTech with thousands of markers—MKMapView on UIKit with dequeueReusableAnnotationView faster than SwiftUI Map. Clustering via MKAnnotationView + MKClusterAnnotation—built-in MapKit, no third-party lib needed.
Android—Google Maps SDK with Jetpack Compose via GoogleMap composable from maps-compose—integrates well with Compose architecture, supports all markers and polylines.
Work Process
Audit requirements: data sources, filters, required integrations (CRM, mortgage broker, notaries). Design data schema and API. Develop map with viewport-loading and clustering. Build filter system. Property card with gallery and virtual tour. Search agent system. Data source integration. Load testing (thousands of markers, complex filters).
Timeline: three-six months depending on platform count, filter complexity, integration scope.







