Разрешения и приватность
Мобильные приложения запрашивают разрешения: камера, геолокация, контакты, уведомления. Правильная работа с ними — обязательна.
Зачем разрешения
Операционная система защищает пользователя. Приложение не может получить доступ к камере или геолокации без явного согласия. Это требование Apple и Google — без него приложение не пропустят в сторах.
Запрос разрешения
Expo предоставляет универсальный API:
import * as ImagePicker from 'expo-image-picker';
async function pickImage() {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
Alert.alert('Нет доступа', 'Разрешите доступ к галерее в настройках');
return;
}
const result = await ImagePicker.launchImageLibraryAsync();
if (!result.canceled) {
setImage(result.assets[0].uri);
}
}
Проверка без запроса
const { status } = await ImagePicker.getMediaLibraryPermissionsAsync();
if (status === 'undetermined') {
// ещё не спрашивали
} else if (status === 'granted') {
// разрешено
} else if (status === 'denied') {
// отказано
}
Открыть настройки
Если пользователь отказал:
import * as Linking from 'expo-linking';
Linking.openSettings();
Описание в app.json
iOS требует описание, зачем нужно разрешение:
{
"expo": {
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "Приложение использует камеру для фото профиля",
"NSPhotoLibraryUsageDescription": "Приложение открывает галерею для выбора фото",
"NSLocationWhenInUseUsageDescription": "Приложение показывает ближайшие точки на карте"
}
},
"android": {
"permissions": ["CAMERA", "READ_MEDIA_IMAGES", "ACCESS_FINE_LOCATION"]
}
}
}
Без описания iOS-приложение крашится при запросе.
Основные разрешения
- Камера —
expo-camera - Галерея —
expo-image-picker - Геолокация —
expo-location - Контакты —
expo-contacts - Уведомления —
expo-notifications - Микрофон —
expo-av - Календарь —
expo-calendar
Хук usePermission
function usePermission(requestFn: () => Promise<{ status: string }>) {
const [status, setStatus] = useState<'undetermined' | 'granted' | 'denied'>('undetermined');
async function request() {
const { status } = await requestFn();
setStatus(status as 'granted' | 'denied');
return status;
}
return { status, request };
}
Приватность
- Не запрашивай разрешения заранее — только когда нужно
- Объясняй, зачем нужно разрешение
- Не используй данные без согласия
- Храни персональные данные безопасно
App Tracking Transparency (iOS)
Для рекламы и трекинга:
import { requestTrackingPermissionsAsync } from 'expo-tracking-transparency';
const { status } = await requestTrackingPermissionsAsync();
Без разрешения нельзя трекать пользователя.
Итоги
- Разрешения обязательны
- Запрашивай только при необходимости
- Описание в
app.jsonдля iOS Linking.openSettingsдля отказа- ATT для трекинга
- Приватность — закон