App Store reviews aren’t enough as feedback. Users don’t actively volunteer it. When something breaks, they quietly uninstall. Across my 12 iOS apps, here’s how I break that pattern.
I use three different approaches to collect in-app feedback. Each catches a different user at a different moment.
Approach 1: passive feedback button
A “Send feedback” button on the settings screen. The user taps proactively.
Implementation:
– Button in the Settings view
– Tap opens a sheet
– Form: message text field + optional screenshot + submit
– Sent to the backend, forwarded to email
Pros:
– Non-intrusive
– Captures users who genuinely have something to say
– Quality feedback (they chose to spend the time)
Cons:
– Only about 0.5% of users tap it
– It’s hidden, many users never see it
– Only catches the most motivated
This is the default I drop into every app from day one. Minimum effort, a baseline feedback channel.
Approach 2: event-triggered inline prompts
A short prompt after the user does a particular action. “How did this go?”
Example scenario:
– The user finishes their 3rd brushing session
– Dentii shows a subtle banner: “How are you finding Dentii?”
– Thumbs up / thumbs down
– Thumbs down opens the full feedback form
– Thumbs up triggers the App Store rating prompt
Implementation:
if user.completed_brushing_count == 3 && !user.has_been_prompted {
showFeedbackPrompt()
user.has_been_prompted = true
}Pros:
– High response rate (20 to 30%)
– Chance to push happy users toward the App Store
– Route unhappy users into the detailed form
Cons:
– Can interrupt at the wrong moment
– Used too often it causes fatigue
– Implementation complexity
Best practice: after onboarding and after a major milestone. Never more than one prompt per day.
Approach 3: shake to report
Shake the iPhone, the feedback form opens. For power users.
Implementation:
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if motion == .motionShake {
presentFeedbackForm()
}
}Pros:
– Invisible but powerful
– Used by power users who think like developers
– Can be triggered from any screen
Cons:
– Most users don’t know about it
– Needs teaching during onboarding (“shake to send feedback”)
– Accidental shakes in cars or on the metro
Valuable mostly in beta testing. On a public release it sees little use.
Feedback form design
Form UX matters. A long form gets 10% completion. A short one gets 60%.
The form schema I use:
- Rating (optional): 1-5 stars or thumbs up/down
- Category picker: Bug report / Feature request / General comment
- Message text field: required, but with a guiding placeholder like “for example, I saw this error on screen X”
- Screenshot attach: optional, but the current screen is attached by default
- Email (optional): only if they want a reply
- Submit button
Auto-attached context (invisible to the user):
– User ID (anonymised)
– App version, build number
– iOS version, device model
– The last 10 user actions (what they did, which screens)
– Crash logs from the last 7 days
– Network status, storage remaining
Without this context debugging feedback is basically impossible.
The backend side
Where does the feedback land?
Option A: Email. Easy start. A custom destination email. Form submit goes to your@email.com.
Option B: Custom dashboard. Collect feedback on your own backend, manage it in an admin panel. Categorise, status (new/in-progress/done), prioritise.
Option C: Third-party. Instabug, Shake.io, Firebase Feedback, ready-made SaaS solutions.
My default: Option A (email) at the start. Once I hit 50+ feedbacks a month I move to Option B (custom dashboard).
Who annotates the screenshot?
The user can attach a screenshot. But feedback gets much more valuable if they can annotate it (arrow, circle, text).
Built-in annotation:
– PencilKit framework (iOS 13+)
– UI overlay with draw gestures
– Export the annotated image
Five minutes of implementation. Doubles feedback quality.
Response loop
The user submits feedback. What happens next?
Bad: nothing. They never send feedback again.
OK: an automated “thanks” email. At least the user knows the message went through.
Good: the developer sends a real reply. “We’re looking at this bug, we’ll fix it in the next update.”
Best: a follow-up email when it’s resolved. “You reported this bug 3 weeks ago, it’s fixed in this update.”
That loop turns feedback-motivated users into brand advocates.
Spam filtering
A public feedback button attracts spam. Rate limit plus basic validation:
- Max 3 feedbacks per user ID per 10 minutes
- Reject feedback shorter than 10 characters
- Filter known spam patterns (links, promos)
- Track spam history per user ID
Those filters eliminate about 95% of spam.
A/B test to optimise
Measure feedback completion rate in production:
- Form showing: how many times it opened
- Form completion: how many times it was submitted
- Completion rate: submit / showing
Test different variants:
– Short form vs long form
– Required email vs optional
– 1-5 stars vs thumbs up/down
– Screenshot default on vs off
After 3 to 4 weeks of A/B testing you’ll know the optimal form.
In-app vs App Store review
When a user wants to give feedback they have two paths: in-app or an App Store review. These should be separated.
In-app feedback: private, only you see it. If there’s a problem you debug and fix.
App Store review: public, everyone sees it. It also hits your rating.
Strategy: ask for in-app feedback first. Thumbs up, route them to the App Store (ask for a review). Thumbs down, pull them into the in-app form (away from the public rating).
This pattern protects your App Store rating and keeps negative feedback in a private channel.
Practical benchmarks
Across my apps:
- Feedback button (passive): 0.3 to 0.5% of users per month
- Event-triggered prompt: 15 to 25% response rate
- Shake gesture: 2 to 4% of users per month (mostly beta testers)
For meaningful feedback volume, event-triggered prompts are essential. Passive alone isn’t enough.
Takeaway
In-app feedback collection is a critical part of iOS app quality. App Store reviews don’t cut it, you need an in-app channel to catch silent uninstalls.
Use all three approaches together: passive button (baseline), event-triggered prompt (volume), shake gesture (power users). Keep the form short, auto-attach context, close the response loop.
Discipline: review all feedback weekly. Categorise each one, push the top 10 into the product backlog. Don’t let feedback go to waste.