SwipeClean Development Journal
SwipeClean: Development Journal
What It Is
Tinder for your camera roll. Swipe left to delete, right to keep. 60-second timed rounds with XP, streaks, and boss battles. The idea started simple: people have thousands of photos they'll never look at again. Make cleaning them up feel like a game instead of a chore.
Architecture
Why @Observable Over ObservableObject
Swift 6 concurrency made the choice easy. @Observable is cleaner, has less boilerplate, and works better with SwiftUI's rendering pipeline. ObservableObject with @Published properties feels like the old way now. The migration was painless because the app was built from scratch.
SwiftData for Persistence
XP totals, streak counts, achievement progress, settings. All stored locally with SwiftData. No backend, no sync, no accounts. Everything stays on the user's device. Privacy isn't a feature, it's the default.
PhotoKit Batch Operations
Apple requires user confirmation for photo deletion. You can't silently delete photos (good). SwipeClean batches deletions at the end of each round and presents a single confirmation dialog. The user sees exactly what they're deleting before anything is permanent.
The Gamification System
This is where most apps get lazy. They add points and call it gamification. That's not gamification. That's a counter.
XP Structure
- Base XP per photo deleted (not kept, deleted, because that's the hard action)
- Round completion bonus for finishing the full 60 seconds
- Streak multipliers that increase daily (1x, 1.5x, 2x, 2.5x, 3x)
- Boss Battles: delete N photos of a specific type (screenshots, duplicates) for a 500 XP bonus
Leveling
7 levels with titles that actually mean something:
| Level | Title | XP Required |
|---|---|---|
| 1 | Data Hoarder | 0 |
| 2 | Casual Cleaner | 500 |
| 3 | Photo Surgeon | 2,000 |
| 4 | Digital Minimalist | 5,000 |
| 5 | Storage Warrior | 12,000 |
| 6 | Deletion Expert | 25,000 |
| 7 | Zen Master | 50,000 |
Streak System
Daily streaks with freeze protection. Free tier gets 1 freeze per week. Pro gets 3. Missing a day without a freeze resets the streak and the multiplier. Real consequences make the streak feel valuable.
Monetization
- Free tier: 5 minutes of swiping per day, 3 undos per day
- Pro (lifetime IAP): Unlimited everything. One payment, done forever.
- Rewarded ads: Watch a 30-second ad for 3 extra minutes. Max 3 per day.
No subscriptions. Lifetime purchase or free with limits. Simple.
The Spring Physics
The card swiping had to feel physical. Not animated, physical.
- Snap-back:
.spring(response: 0.4, dampingFraction: 0.7)for cards that don't cross the threshold - Fly-away:
.easeOut(duration: 0.3)for committed swipes - Drag threshold: 30% of screen width before a swipe commits
- Max rotation: 15 degrees at full drag distance
These numbers came from testing on device for hours. The defaults feel floaty. These feel like you're flicking a real card.