Developing Product Recommendations System in Mobile Apps
A recommendation system is not just "often bought with this product". This is an infrastructure that collects behavioral signals, trains a model, and delivers personalized results at the right moment. Without properly structured event tracking, the model will recommend popular products instead of relevant ones — and the user won't feel the difference from "top sales".
Architecture: what the system consists of
A recommendation system has three layers, and mobile app participates in each.
Event collection. App generates behavioral signals: product view, cart addition, purchase, time on screen, swipe scroll through feed. These events go to analytics system (Amplitude, Mixpanel, Segment, own Kafka topic). Data quality is critical: if view_product fires on every scroll past a card — the model gets noisy signal.
Model and offline training. Collaborative filtering (Matrix Factorization, ALS), content-based filtering by product attributes, or hybrid approaches. For e-commerce with cold start (new users, new products) pure CF doesn't work — need fallback strategies based on attributes.
Recommendations delivery. Mobile app requests recommendations via API, gets ordered product list. Important here: response time (< 200ms for inline blocks), cache TTL, degradation on service unavailability.
Event tracking in mobile app
Most common oversight — wrong definition of product "view". viewDidAppear on product screen fires before user actually sees content. For impression tracking in lists use UICollectionView.indexPathsForVisibleItems with timer:
// iOS: count impression only if product visible > 1 second
private var impressionTimers: [IndexPath: Timer] = [:]
func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] _ in
guard let product = self?.products[indexPath.item] else { return }
Analytics.track(.productImpression(productId: product.id, source: .recommendations))
}
impressionTimers[indexPath] = timer
}
func collectionView(_ collectionView: UICollectionView,
didEndDisplaying cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
impressionTimers[indexPath]?.invalidate()
impressionTimers.removeValue(forKey: indexPath)
}
On Android equivalent — RecyclerView + custom OnScrollListener or ViewTreeObserver.OnGlobalLayoutListener with Intersection Observer logic.
Recommendations API integration
Recommendations come in several types with different UI integration points:
| Type | Place in UI | Request context |
|---|---|---|
| Homepage feed | Home screen | user_id |
| Similar items | Product screen | product_id, user_id |
| Cross-sell | Cart | cart_items[], user_id |
| Post-purchase | Thank you screen | order_id, user_id |
For each type — separate endpoint or placement parameter. Not one universal "give me recommendations" request.
Caching: homepage recommendations cached for 30–60 minutes (NSCache on iOS, Room + WorkManager on Android for background preload). Product screen recommendations — don't cache or TTL 5 minutes, should account for current session.
Cold start and fallback
New user — no history, no vector. Options:
- Onboarding with category interest selection → pass as initial signals
- Popular products in category (editorial picks, not just top sales)
- Geo-based recommendations (what's bought in this region)
Fallback when recommendation service unavailable: pre-made static list "editorial selection" in config or CDN.
A/B testing
Recommendation system without A/B test is faith in the model. Validate every new algorithm via Feature Flags (Firebase Remote Config, Unleash): 10% traffic on new model, metric — CTR of recommendation block and purchase conversion with 7-day attribution window.
Workflow
Audit current event tracking: what's already collected, what needs to be added.
Design event schema: event names, required parameters, context.
Integrate recommendation API or develop model (if no ready service).
Implement UI components: horizontal scroll, carousel, inline block, with correct impression tracking.
Caching, fallback on errors, offline mode.
A/B testing setup, success metrics definition.
Timeline guidelines
Integrate existing recommendation API into app — 1–2 weeks. Develop system from scratch including data collection, model, API, and mobile part — 2–3 months. Price calculated individually after analyzing current stack and catalog size.







