How to Add Camera, Notifications, and Other Device Features to a Vibecode iOS App

Vibecode apps can use iOS device capabilities like the camera, location, and push notifications through Expo modules. Here is how to add them correctly, including the permission strings iOS demands.

How Device Features Work in Vibecode

Because Vibecode builds on Expo, device features come from the Expo ecosystem of modules rather than raw Swift APIs.

When you ask for the camera, notifications, or location, the AI wires up the corresponding Expo capability and the UI around it.

The important part is that iOS treats device access as privacy-sensitive. Every capability needs both a runtime permission request and a declared usage description.

Get the permissions and descriptions right and these features are straightforward. Get them wrong and iOS will crash the app or App Review will reject it.

Prerequisite: You Need a Development or Production Build

Some device features do not work in the basic Expo Go preview and require a development build or a production build.

If you plan to use anything beyond the modules bundled in Expo Go, expect to create a development build early. It behaves like your real app with the native modules compiled in.

This matters because a feature can appear broken in Expo Go when it simply needs a proper build to run.

So before debugging a device feature for hours, confirm you are testing in the right kind of build.

Adding Camera and Photo Access

To let users take photos or pick images, ask Vibecode to add camera and media library access using the Expo image and camera modules.

iOS requires usage-description strings such as a camera usage description and a photo library usage description. Without them, the app crashes the moment it requests access.

Always request permission at the point of use and handle denial gracefully. Show a clear message and a path to Settings if the user declined.

Test on a real device. Camera behavior in a simulator is limited and can mislead you about how it feels in the hand.

Adding Location

Location is powerful and heavily scrutinized. Ask Vibecode to add location access via the Expo location module and be explicit about foreground versus background use.

iOS needs a location usage description string, and background location requires additional justification. Request only what your feature genuinely needs.

Handle the permission states: granted, denied, and reduced accuracy. Users can grant approximate location, so your UI should not assume pinpoint coordinates.

App Review pays close attention to location. Be ready to explain in your submission exactly why the app needs it.

Adding Push Notifications

Push notifications on iOS involve more moving parts than most features. They require user permission, a device token, and a server or service to send messages.

Ask Vibecode to set up notifications using Expo's notifications capability. For real remote push, iOS also requires the Apple Push Notification service and appropriate credentials configured in your build.

Request notification permission thoughtfully, ideally after explaining the value, since a hasty denial is hard to reverse.

Test both local notifications and remote push on a physical device. Remote push generally will not work in a simulator, so a real iPhone is required.

Declaring Permissions Correctly

The single most common cause of device-feature failures is a missing usage-description string. iOS mandates a human-readable reason for every sensitive capability.

In your Expo config, ensure each capability has its matching usage description: camera, photo library, location, microphone, and so on.

Write honest, specific descriptions. "We use your camera to let you attach photos to entries" is better than a vague sentence, both for users and for reviewers.

After adding or changing permissions, rebuild. Permission declarations are baked into the native build, so a preview alone will not reflect them.

Testing and Handling Denials

A robust app assumes users will say no. Every device feature needs a graceful path when permission is denied.

Detect the denied state and show a helpful message rather than a dead button. Offer a link to the system Settings so users can change their mind.

Re-test each permission by resetting it in iOS Settings and launching fresh. This reveals the true first-run experience.

Ask Vibecode explicitly to handle denial states if the generated code only covers the happy path. AI often optimizes for the success case and skips the edges.

Request Permissions at the Right Moment

When you ask for a permission matters almost as much as whether you declare it.

Request access at the point of use, right when the user taps the feature that needs it, rather than firing every prompt on first launch.

Context raises acceptance. A user who just tapped "attach photo" understands why the camera prompt appears; the same prompt on a cold start feels intrusive and gets denied.

A denial is hard to reverse, because iOS will not re-prompt once the user says no. After that they must change it in Settings, so it is worth earning the yes the first time.

Ask Vibecode to gate each request behind the relevant user action, and confirm on device that the prompt appears only when it should.

Write Usage Descriptions That Pass Review

The usage-description strings are not just a technical checkbox; App Review reads them.

Each string should state plainly why your app needs the capability, in language a user would understand. Vague or missing reasons draw scrutiny.

Compare a weak string like "This app uses your location" with a specific one like "We use your location to show workouts near you." The specific version helps both users and reviewers.

Match the description to what the app actually does. If you request a permission the app never visibly uses, expect questions or a rejection.

After editing these strings, rebuild, because they are compiled into the native app and will not update from a preview alone.

Test the Full Permission Lifecycle

Device features are only as good as their behavior across every permission state, so test the whole lifecycle, not just the happy path.

Start fresh: reset the permission in iOS Settings, relaunch, and confirm the first-run prompt appears at the right moment.

Then test the denied path. Deny the permission and verify the app shows a helpful message and a route to Settings rather than a dead button or a crash.

For location, also test reduced accuracy, since users can grant approximate location and your UI must not assume exact coordinates.

Repeating this reset-and-relaunch cycle for each capability is the only reliable way to see what a real new user experiences.

Match Capabilities to a Real User Need

Every device capability you add is something App Review will weigh, so add them deliberately.

Before requesting the camera, location, or notifications, be able to state the concrete user benefit in one sentence. If you cannot, reconsider the feature.

Apple looks unfavorably on apps that request sensitive access without a clear, visible purpose. A permission you never actually use invites rejection.

Requesting only what you genuinely need also builds user trust. People are more willing to grant access when the reason is obvious and the request arrives in context.

This discipline keeps both your users and the reviewers on your side.

When You Hit the Limits

Not every native capability is available through Expo modules, and brand-new iOS APIs can lag behind.

If you need something the ecosystem does not cover, you may have to write or install a native module. That is a real development task beyond prompting.

At that point the app is no longer fully no-code, and you should be comfortable in the React Native/Expo codebase or bring in someone who is.

This is the honest ceiling of AI builders: common device features are easy, but deep or novel native integration eventually requires real native work.

Frequently Asked Questions

Why does my camera feature crash the app on iOS?

Almost always a missing usage-description string. iOS requires a declared reason for camera access, and its absence causes an immediate crash when access is requested.

Do device features work in Expo Go?

Some do, but many require a development or production build with the native modules compiled in. Test in the correct build type before assuming a feature is broken.

Can I do remote push notifications with Vibecode?

Yes, through Expo's notifications capability plus Apple's push service and proper credentials. Test remote push on a physical device, not a simulator.

What if Expo does not support a native feature I need?

You may need a custom or third-party native module, which is a real coding task. At that point the app is no longer purely no-code.

How do I handle users denying permission?

Detect the denied state, show a helpful message, and link to iOS Settings. Ask Vibecode explicitly to handle denials if the generated code only covers success.