C.W.K.
Stream
Lesson 04 of 05 · published

Mobile Plugins & Permission Prompts

~13 min · tauri, mobile, plugins, permissions

Level 0Web Tourist
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"On mobile there are two permission systems stacked: Tauri's capability ACL, and the OS's runtime prompts. You answer to both."

Powers the Phone Has That the Desktop Doesn't

Mobile unlocks plugins with no desktop equivalent: barcode-scanner, biometric (Face ID / fingerprint), nfc, haptics, geolocation, and more. They're added the same three-surface way (Cargo, builder, capability) but many include native iOS/Android code under the hood. Reach for these to make a Tauri mobile app feel genuinely native — a web page in a browser can't tap the fingerprint sensor; your Tauri app can.

Two Permission Layers

Desktop had one gate (Tauri capabilities). Mobile stacks a second: the OS runtime permission prompt. Granting geolocation:default in your capability lets your app ask for location — but iOS/Android still show the user a system dialog at runtime, and the user can deny it. Your code must handle 'permission requested and refused,' not assume a capability grant means access. Design for the denial path; on mobile it's common.

The Manifest Strings You Must Not Forget

iOS requires a human-readable usage description for every sensitive capability (camera, location, etc.) in Info.plist; omit it and the app is rejected by App Review or crashes when it tries to access the resource. Android declares its permissions in AndroidManifest.xml. These live in the generated platform projects, and getting them right is a hard requirement, not a nicety — a missing iOS usage string is one of the most common first-submission rejections.

Code

Capability + OS prompt, with a real denial path·tsx
import { checkPermissions, requestPermissions, getCurrentPosition }
  from "@tauri-apps/plugin-geolocation";

// Two gates: capability grants the ability to ask; the OS asks the user.
let perm = await checkPermissions();
if (perm.location !== "granted") {
  perm = await requestPermissions(["location"]); // OS dialog shows here
}
if (perm.location === "granted") {
  const pos = await getCurrentPosition();
  console.log(pos.coords.latitude, pos.coords.longitude);
} else {
  // The user said no. Handle it — this path is common on mobile.
}

External links

Exercise

Pick a mobile-only plugin (geolocation, biometric, or barcode-scanner) and write the full permission flow: check, request (which triggers the OS dialog), and handle BOTH granted and denied outcomes. Then note where the iOS usage string would go. You're practicing the two-layer permission reality that desktop never made you think about.
Hint
Flow: checkPermissions → requestPermissions (OS dialog) → branch on the result. The iOS usage string goes in the generated Apple project's Info.plist (e.g. NSLocationWhenInUseUsageDescription). Always write the denied branch — users say no.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.