How to Collect Feature Requests in Your iOS App

Most developers learn about feature requests from App Store reviews, support emails, and the occasional tweet. That's a noisy channel. By the time you read "please add dark mode," you're already three sprints into something else, and there's no way to know if one user or a hundred users wanted the same thing.
Collecting feature requests directly inside your iOS app gives you structured, votable data at the moment users hit a gap. This guide covers three practical approaches, with real Swift code and the tradeoffs for each so you can pick the right one for your app.
To collect feature requests in your iOS app, you have three options: a native Swift SDK like FeaturePulse (SPM, SwiftUI, iOS 16+) that embeds a voting board natively in your app, a hosted board opened in SFSafariViewController with three lines of Swift, or a custom-built form. Most indie developers start with the in-app browser approach because it ships in a day and works across iOS and Android from one dashboard.
Why App Store Reviews Don't Replace a Feature Board
The App Store review prompt (SKStoreReviewRequest) captures satisfaction, not demand. Apple throttles it to a maximum of three prompts per year per user, so you get at most three moments per year where the request appears — and most users tap a star rating without leaving a comment. Feature requests buried inside two-sentence reviews are invisible to other users, can't accumulate upvotes, and give you no signal about how many people actually want the same thing.
iOS developers typically rely on three passive channels: App Store reviews, support emails, and crash reports from tools like Firebase Crashlytics. These channels capture pain, not preference. A user who wants a dark mode, a CSV export, or a home screen widget rarely files a support ticket about it. They tolerate the gap and eventually move on. In-app collection changes the equation in three ways. A voting board surfaces aggregate demand: 47 upvotes on "add widget support" tells you more than 47 separate emails sent over six months. The status workflow — pending, under review, approved, in progress, planned, completed — closes the feedback loop so submitters can see their request move forward, which matters for power user retention. And the alternative to buying a $5/month tool is building the feedback layer yourself, which runs 80-120 development hours before you've written a single line of product code. For most iOS developers, that's the wrong place to spend those hours.
Option 1: Native Swift SDK
A native Swift SDK embeds the feature request board directly in your app as SwiftUI views. Users browse existing requests, upvote what they care about, and submit new ones without leaving the app or seeing any browser chrome.
FeaturePulse is one example. It distributes via Swift Package Manager, requires iOS 16+ and Swift 6.0+, and renders using SwiftUI. You add the SPM package, initialize with your API key, and present the request list in whatever mode fits your app's UX: a full-screen view, a modal sheet, a tab bar item, or a CTA banner.
import FeaturePulse
// Initialize in app startup
FeaturePulse.shared.configure(apiKey: "your-api-key")
// Present as a sheet from any SwiftUI view
.sheet(isPresented: $showFeedback) {
FeaturePulseView()
}
User identification ties into your existing auth system via a custom user ID. The dashboard shows which users submitted which requests and tracks payment tier context, which is useful for weighting enterprise requests more heavily. WishKit is another iOS-focused option in this category with similar SwiftUI-based integration.
What native SDKs do well: Fully native UI, no browser chrome, tight integration with your app's auth layer and theming.
Where they fall short: A native iOS-only SDK covers iOS only. If your app ships on Android — or if you plan to add an Android version — votes from Android users go to a separate board or nowhere at all, unless you do a second integration. Most iOS SDKs in this category require iOS 16+, which excludes users on older OS versions.
Option 2: In-App Browser with SFSafariViewController
SFSafariViewController, available since iOS 9 (2015), opens any URL inside a native Safari sheet that slides up over your app. From the user's perspective it looks and behaves natively: they see standard Safari controls, can scroll and interact with the page, and dismiss with a swipe or Done button. You control when it opens; they never fully leave your app.
If your feature board lives at a public URL, you can open it with three lines of Swift:
import SafariServices
let url = URL(string: "https://pickafeature.com/b/your-project")!
let safari = SFSafariViewController(url: url)
present(safari, animated: true)
That's the complete integration. No SPM dependency, no SDK to pin a version on, no app update required when the board's backend changes.
The hosted board approach pays dividends for cross-platform teams. iOS users opening the board via SFSafariViewController and Android users opening the same URL via Chrome Custom Tabs both submit to the same dashboard. If you later add a React Native or Flutter build, those users write to the same board too — votes pool rather than fragment. The feedback board for mobile app guide covers the full cross-platform setup in detail.
What the hosted board approach does well: Ships in a day, zero SDK maintenance, one voting pool for all platforms, works on iOS 9+.
Where it falls short: You can't automatically identify the signed-in user from your app's auth layer without passing context via URL parameters. Anonymous voting works fine (pick a feature uses a browser UUID for anonymous submissions), but tying requests to specific user accounts requires extra wiring. The board also appears as an overlay rather than a seamlessly embedded native view.
Option 3: Build Your Own Form
A custom form is a title field, a description field, and a submit button wired to your own backend table. Straightforward to build.
The hidden work is everything else: upvoting with per-user deduplication, moderation tools to approve requests before they're public, a status workflow to move cards through stages, email notifications when status changes, and a way to surface the request list back inside the app. Production-quality implementation runs 80-120 hours. You own the hosting, the maintenance, and every future iteration.
This makes sense when your feedback system has requirements that no off-the-shelf tool supports: deeply custom fields per subscription tier, complex voting rules, or tight integration with internal data pipelines. For most iOS developers, it's the wrong place to spend those hours.
How to Choose the Right Approach
The main factor is whether you also ship Android.
iOS-only app with a SwiftUI codebase: A native Swift SDK like FeaturePulse gives the cleanest integration. Users stay fully inside your app, the UI matches your theming, and there's no browser to deal with.
Cross-platform app (iOS plus Android, React Native, or Flutter): Hosted board via in-app browser. One dashboard, one voting pool, no duplicate integrations. For teams on Flutter, the Flutter SDK gives you a native-feeling PickAFeatureScreen that covers iOS, Android, macOS, and web from a single install. See the Flutter feature request widget guide for the pub.dev setup.
Already have your own backend and want full control: Build it. Budget 100+ hours and make sure your requirements genuinely justify it.
Setting Up pick a feature on iOS
pick a feature supports iOS through its hosted public board at pickafeature.com/b/your-slug. No SPM package, no SDK version pinning, no app update required when the board changes.
Step 1: Create a project at pickafeature.com. The free tier covers 1 project with 10 feature requests — no credit card needed. After setup you'll have a public board URL and a dashboard with moderation tools.
Step 2: Copy your board URL. In the project dashboard, find the Public Board link. It looks like pickafeature.com/b/your-slug where the slug is editable.
Step 3: Add a button to your app. Wire any button (settings screen, help menu, feedback tab) to open the board in SFSafariViewController:
import SafariServices
@objc func openFeatureBoard() {
guard let url = URL(string: "https://pickafeature.com/b/your-slug") else { return }
let safari = SFSafariViewController(url: url)
safari.preferredBarTintColor = UIColor.systemBackground
present(safari, animated: true)
}
Anonymous submissions work automatically via browser UUID. For apps with user accounts, pass identity through URL parameters or let users enter their email inside the board when they submit.
Incoming requests land in the dashboard in "pending" state. Approve them to make them visible on the public board and inside the SDK widget. The how to collect feature requests in a mobile app guide covers the full moderation and deduplication workflow.
Pricing: free for 1 project, $5/month for 3 projects with unlimited requests, $15/month for unlimited projects.
Frequently Asked Questions
Can I collect feature requests without adding any SDK to my iOS app?
Yes. SFSafariViewController opens a hosted feature board inside your app without any SPM dependency or SDK integration. Three lines of Swift is the complete implementation. The tradeoff is you can't automatically pass your app's current user session to the board — anonymous voting still works via browser UUID, but tying submissions to specific accounts requires passing a token or email via URL parameters.
What's the difference between FeaturePulse and pick a feature for iOS?
FeaturePulse is a native SwiftUI SDK (iOS 16+, SPM) that embeds fully inside your app with no browser overlay. pick a feature supports iOS through a hosted board in SFSafariViewController and also ships a Flutter SDK for native embedding across iOS, Android, macOS, and web from one codebase. If you're iOS-only and want zero browser chrome, a native SDK fits better. If you're cross-platform or want one dashboard for all your platforms, pick a feature's hosted board approach pools votes from all of them.
Do votes from iOS and Android users count together?
With a native iOS-only SDK, votes are iOS-only and go to that SDK's backend. With pick a feature's hosted board, iOS users (SFSafariViewController) and Android users (Chrome Custom Tabs) both submit to the same project. Votes pool into one ranked list and the dashboard breaks them down by platform, so you can spot requests that are specific to one OS.
Does the SFSafariViewController approach pass App Store review?
Yes. SFSafariViewController is a standard Apple API widely used for OAuth flows, in-app help pages, and content browsing. Apple has no policy against opening external URLs in SFSafariViewController — it's the documented way to show web content without forcing a full app switch. The feature board loads from your project's public URL as a normal web page.
How do I prevent spam submissions from anonymous iOS users?
Every submission lands in a "pending" state and needs your approval before it's visible on the public board or inside any SDK widget. Anonymous submissions are tied to a browser UUID, so one device generates one submission per idea. The moderation dashboard lets you approve, reject, or edit requests before they surface to other users.
If you want a feature request board running in your iOS app today, pick a feature's free tier covers one project with no card required. Open the board in SFSafariViewController for a three-line integration, or use the Flutter SDK if you're building cross-platform. Start at pickafeature.com.