Expo Pedometer iOS端异常咨询:权限已申请但无法获取步数
Hey there, let's work through these pedometer problems step by step—they're definitely fixable once we untangle the import confusion and iOS-specific quirks!
1. Sort Out the Import Syntax First
The docs' mixed signals here are frustrating, but the key fact is: the standalone expo-sensors package is deprecated, and all Pedometer functionality is now baked directly into the main expo package. Stick with your original import to avoid Android's "date functionality not implemented" error:
import { Pedometer } from 'expo';
This aligns with the current maintained version of the API, so you can ditch the expo-sensors import entirely.
2. Resolve the iOS Promise Rejection
Even if permissions seem to be granted, iOS can reject the Pedometer promise for a few common reasons. Let's address each:
a. Double-Check Permission Status
Just seeing the permission prompt doesn't guarantee it was actually granted. Add explicit permission checking before any Pedometer calls:
import { Permissions } from 'expo'; // For SDK <33; use `expo-permissions` for newer versions async function checkPedometerPermissions() { const { status } = await Permissions.askAsync(Permissions.PEDOMETER); if (status !== 'granted') { this.setState({ pedometerAvailability: "Pedometer permission denied" }); return false; } return true; } // Use it before calling Pedometer methods const hasPermission = await checkPedometerPermissions(); if (!hasPermission) return;
This ensures you're not trying to access the pedometer without proper authorization.
b. Fix Date Handling for iOS
iOS is picky about the date objects passed to Pedometer. Your Moment.js usage might be creating incompatible date instances—try simplifying with native Date methods:
const diaryDate = new Date(); // Replace with your actual diary date value let endDay = new Date(diaryDate); let startDay = new Date(diaryDate); const today = new Date(); // Check if we're querying a past date (compare full date strings, not just day of week) if (today.toDateString() !== endDay.toDateString()) { endDay.setHours(23, 59, 59, 999); // Add milliseconds for precise end-of-day } startDay.setHours(0, 0, 0, 0); // Set start-of-day with milliseconds // Now fetch step count Pedometer.getStepCountAsync(startDay, endDay) .then(result => this.setState({ stepCount: result.steps })) .catch(error => this.setState({ stepCount: `Could not get stepCount: ${error.message}` }));
Using toDateString() fixes the bug where different dates could share the same day of the week (e.g., two Mondays), and adding milliseconds ensures iOS recognizes the full date range correctly.
c. Test on a Physical iOS Device
iOS simulators don't reliably mock pedometer data—Apple's simulator often fails to return valid step counts even if code is correct. Always test this feature on a real iPhone/iPad to rule out simulator-specific issues.
3. Quick Debugging Tips
- Log full error details: Instead of just showing the error string, log
error.messageanderror.stackto get context about why the promise is rejecting. - Update Expo SDK: Ensure you're on a recent stable SDK version—older versions had known pedometer bugs that are fixed in newer releases.
Summary
- Stick with
import { Pedometer } from 'expo';to avoid Android errors. - Validate permissions explicitly before accessing the pedometer.
- Simplify date handling to be iOS-compatible, ditching Moment.js quirks for native Date methods.
- Test on a physical iOS device instead of the simulator.
Give these steps a shot, and you should see consistent pedometer behavior across both platforms!
内容的提问来源于stack exchange,提问作者AkhinLinks

