Mysterious Treasure
A location-based treasure hunt where you follow clues to find real prizes hidden around the city.
- iOS
- Android
- 2025
- My own product
Screenshots
Click an image to enlarge it.
About the app
Mysterious Treasure was not a game, it was a treasure hunt contest with real prizes. Prizes were hidden in areas on the map — a phone, a pair of headphones, a gift card — and players solved the published clues trying to be the first to find the prize. Every contest had a deadline; a counter on screen ticked down to the second.
The real technical problem here was not finding a location, it was verifying one. The treasure's exact coordinates were never sent to the phone; the user only saw the approximate area where the treasure was hidden. Otherwise anyone inspecting the app's network traffic could claim the prize without solving a single clue. The "I found it" claim was evaluated on the server rather than taken from the device, and devices reporting a spoofed location were rejected.
"First to find it wins" sounds simple, but underneath it is a race condition problem. When two people find the same treasure almost simultaneously, the prize must not be awarded twice. I reduced the step that picks the winner to a single write inside a transaction: the prize is awarded once, and later requests see that the contest is closed. By the same logic the countdown read the server clock instead of the device clock — you could not buy yourself extra time by changing the phone's date.
For entering a contest I left three paths: an in-app purchased token, a premium membership, or watching a rewarded ad. Letting users who did not want to spend money play too was essential for keeping the product alive; the moment the number of players drops, the contest itself stops meaning anything.
The app is no longer live. There were two reasons: problems came up on the app store policy side and I did not have the time to run a location-based, prize-giving game on my own. An app that is played in the physical world and hands out prizes was the most demanding product I have built, both in terms of policy and day-to-day operations. What I learned about location verification and race conditions has stayed with me; but if I design something similar again, I will factor in store policies and the daily operational load from day one.
Key features
- Treasure discovery on the map: active contests near you and across the city shown on a map
- Clue-based search: solving contest-specific clues to pinpoint where the treasure is hidden
- Server-side location verification: the exact coordinates are never sent to the device, the find claim is verified on the server
- Single-winner guarantee: a transaction-based lock that awards the prize exactly once under simultaneous find requests
- Server-clock countdown: days, hours, minutes and seconds — independent of the device clock
- Three ways to enter: a token, a premium membership, or watching a rewarded ad
- Explore sections: contests near your location, popular ones, newly added ones and ones about to expire
- Contest bulletin: results, treasures coming soon and notifications
- Contests you entered: tracking ongoing and completed entries
- In-app purchase and subscription infrastructure
Technologies used
105 technologies · 12 categoriesLanguages and Platform
- Swift (iOS)
- Java (Android)
- Kotlin (Android)
- Native iOS development
- Native Android development
UI and Application Layer
- UIKit / SwiftUI
- XML Layout / Jetpack Compose
- Auto Layout & Constraints
- UICollectionView / RecyclerView
- Countdown timers
- Permission request flows
- App lifecycle
Backend and Data
- Firebase Firestore
- Cloud Functions (callable)
- Firestore security rules
- Transaction-based lock
- Server timestamp
- Composite indexes and queries
- Firebase Storage
- Authentication and sessions
- Firestore offline cache
- Batch write
- Cursor-based pagination
- Denormalization
- Counter fields
- Cloud Functions triggers
- Scheduled jobs
- Data migration
Location and Maps
- MapKit (iOS)
- Google Maps SDK (Android)
- Core Location (iOS)
- FusedLocationProvider (Android)
- Location permissions (iOS/Android)
- Geographic proximity queries
- Server-side location verification
Real Time and Notifications
- Firestore real-time listeners
- Firebase Cloud Messaging
- APNs (iOS)
- Android notification channels
- Notification permission flow
Payments and Revenue
- StoreKit (iOS)
- Google Play Billing (Android)
- Subscription management
- Server-side receipt validation
- Consumable product (token)
- Rewarded ad integration
Architecture and Patterns
- MVVM / MVC
- Kotlin Coroutines
- async/await & GCD (iOS)
- Repository layer
- Race condition handling
- Client-server trust boundary
- Pagination and caching
Networking and Data Transfer
- URLSession (iOS)
- HTTP client (Android)
- JSON parsing (Codable)
- Retry and timeout
- Offline state handling
- Image caching
- Download and upload queue
- Multipart file upload
- Bandwidth-based quality
Security and Privacy
- Keychain (iOS)
- EncryptedSharedPreferences (Android)
- HTTPS and ATS
- Auth token management
- Session refresh
- Permission rationale strings
- Account deletion flow
- Server-side authorization checks
- Sensitive data masking
UI States and Accessibility
- Dark mode support
- Dynamic Type
- Safe area
- Empty / loading / error states
- Skeleton loading
- Pull to refresh
- Keyboard and focus management
- Deep linking (Universal Links)
- VoiceOver / TalkBack labels
Testing, Debugging and Profiling
- Xcode Instruments
- Android Profiler
- LLDB
- Logcat
- Memory leak tracking
- Network traffic inspection
- Reading crash reports
- Testing on real devices
- Testing across screen sizes
Tools and Release Process
- Xcode
- Android Studio
- CocoaPods
- Gradle
- Git
- App Store Connect
- Google Play Console
- Open source libraries (GitHub)
- TestFlight
- Play Console internal testing
- Version and build numbering
- Signing and provisioning profiles
- App Store review process
- App Privacy / Data Safety form
- Store assets and ASO copy
- App size optimization
Idea, design, UI, code, app store release and post-launch maintenance — I ran the entire process end to end on my own. No team, no agency, no outsourcing.
Development notes
- Languages and approachThe iOS side was written in Swift and the Android side in Java and Kotlin. No cross-platform framework was used; both apps were built with their own platform's native tooling. I have been doing mobile development since 2020.
- No AI assistanceAll of the code was written by hand. This project was built before AI coding tools such as Claude Code and Codex became widespread — no such tool existed at the time.
- DependenciesA large number of open source GitHub libraries and CocoaPods packages were used. Dependency management was handled with CocoaPods on iOS and Gradle on Android.
- Trust boundaryThe treasure's exact coordinates were never sent to the client; the find claim was evaluated on the server to guard against spoofed locations.
- Testing and debuggingTested on real devices, across different screen sizes and under poor network conditions. After launch I read the crash reports and shipped fixes release by release.
- Release processI handled the review process for both stores on my own: App Store Connect and Google Play Console setup, the privacy declaration (App Privacy / Data Safety), release notes, store assets and fixes based on rejection reasons.
- Product ownershipIdea, design, development, backend, app store release and post-launch maintenance — I ran the entire process on my own.
Let's talk about Mysterious Treasure
I am happy to walk you through the technical details, the problems I ran into and how I solved them.