We develop Stories mechanics — ephemeral content — in mobile apps for iOS, Android, and cross-platform. This is a nontrivial UI pattern: progress bars with 60 FPS animation, tap navigation, pause on hold, swipe-down to close, media preloading without delays, and a server-side 24-hour timer. A mistake in any element ruins user experience. Our experience: 10+ years in mobile development, over 50 delivered projects. We'll evaluate your project for free.
How We Implement Progress Bars and Navigation
Horizontal progress bars at the top — UIView with frame.width animation via CADisplayLink (iOS) or ValueAnimator (Android). CADisplayLink provides 60/120 FPS synchronization with the display — smooth animation. Using Timer.scheduledTimer is not recommended: it stutters, especially under load. Duration for one story — usually 5–7 seconds for photos, for video — clip length (but no more than 15 seconds). The video progress bar syncs with AVPlayer.currentTime() via addPeriodicTimeObserver, not with a system timer.
Navigation: tap right half of screen — next story, left half — previous. UITapGestureRecognizer checking location.x > bounds.width / 2. Hold — UILongPressGestureRecognizer with minimumPressDuration: 0.1: on .began pause animation and AVPlayer, on .ended — resume. Swipe-down to close — interactive dismiss via UIPanGestureRecognizer. Scaling and moving the screen with the gesture (transform), on release — either full dismiss or return (UIViewPropertyAnimator).
Why Media Preloading Is Critical
Delay when switching stories is the main UX bug. User taps — waits 1–2 seconds while the photo or video loads. Correct solution: preload the next 2–3 stories. For photos — SDWebImage.prefetchURLs() or Kingfisher ImagePrefetcher. For video — AVAsset.loadValuesAsynchronously(forKeys: ["playable"]) + AVPlayerItem created in advance, AVPlayer not started until display. On Android — Coil ImageLoader.enqueue(ImageRequest) for photo preloading, ExoPlayer with ConcatenatingMediaSource for video: add next item to queue, ExoPlayer preloads buffer. Cache preloaded resources in memory (not just on disk) — repeat viewing of a story within the same session must be instant.
Creating Stories: From Photo to Video
Photo — PHPickerViewController + optional editor (text, stickers). Text over image: UITextView over UIImageView, on save — combine in UIGraphicsImageRenderer. Stickers — UIView with UIPanGestureRecognizer + UIPinchGestureRecognizer + UIRotationGestureRecognizer.
Video — recording via AVCaptureSession directly in the stories camera (like Instagram/Snapchat) or selection from gallery. Recording with 15-second limit — AVCaptureMovieFileOutput.maxRecordedDuration. Hold button to record, release — stop. After creation — upload in background. Story appears in feed immediately with placeholder, replaced by real content after upload.
How the Expiration Timer Works
24-hour timer — server-side, not client. Client simply requests list of active stories. Server filters by created_at + 24h < now. On client, for already loaded stories from cache — check expiresAt on open. If expired — don't show cache, request server (or delete from local storage). Views — mark on server via separate API request after story display. Batch marks: not one request per view, accumulate over session and send on app background or every 30 seconds.
Typical Mistakes When Implementing Stories
| Mistake | Consequence | Solution |
|---|---|---|
Using Timer for progress bar |
Janky animation, desync with video | CADisplayLink on iOS, ValueAnimator on Android |
| Loading media "on the fly" | Delays when switching | Preload next 2-3 stories |
| No in-memory cache | Repeated downloads on return | Cache in NSCache or LruCache |
Ignoring expiresAt on client |
Showing outdated stories | Check time before display |
| Individual view requests | Server load | Batching every 30 seconds |
What's Included
- Documentation (API schemas, flow diagrams)
- Source code with comments
- Access to repository, App Store Connect / Google Play Console
- Integration with your backend (REST/GraphQL)
- Testing on real devices (iOS 15+, Android 10+)
- Post-release support for 1 month
Timeline and Cost
Story viewing with progress bars, preloading, navigation, and expiration timer — 3–4 days. Creation with camera, text, and stickers + upload — another 2–3 days. Cost is calculated individually after analyzing your project. Contact us for a consultation and preliminary estimate.
| Component | Time (days) |
|---|---|
| Viewing mechanics (progress bars, gestures, timer) | 3-4 |
| Media preloading and caching | 2-3 |
| Story creation (camera, editor, upload) | 2-3 |
| Backend integration and testing | 2-3 |
| Total | 7-10 |
More details on stories mechanics can be found in the App Store Review Guidelines (Section 4.2 and 5.1) and Google Play documentation.
Our team — 10+ years of mobile development experience, guaranteeing quality and on-time delivery. Order stories development for your app — we'll evaluate the project within 1 day.







