# Примеры использования API для мобильной разработки ## 🚀 Быстрый старт ### 1. Авторизация пользователя ```javascript // Регистрация const registerUser = async (userData) => { const response = await fetch('http://192.168.0.103:8000/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: userData.username, email: userData.email, password: userData.password, full_name: userData.full_name, phone: userData.phone }) }); return await response.json(); }; // Вход в систему const loginUser = async (username, password) => { const response = await fetch('http://192.168.0.103:8000/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); // Сохранить токен для дальнейших запросов localStorage.setItem('access_token', data.access_token); return data; }; ``` ### 2. Создание SOS оповещения ```javascript const createEmergencyAlert = async (location, alertType, message) => { const token = localStorage.getItem('access_token'); const response = await fetch('http://192.168.0.103:8000/api/emergency/alerts', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ latitude: location.latitude, longitude: location.longitude, alert_type: alertType, // 'general', 'medical', 'violence', etc. message: message, contact_emergency_services: true, notify_emergency_contacts: true }) }); return await response.json(); }; ``` ### 3. Поиск ближайших оповещений ```javascript const findNearbyAlerts = async (userLocation, radiusKm = 5) => { const token = localStorage.getItem('access_token'); const response = await fetch( `http://192.168.0.103:8000/api/emergency/nearby?latitude=${userLocation.latitude}&longitude=${userLocation.longitude}&radius_km=${radiusKm}`, { headers: { 'Authorization': `Bearer ${token}` } } ); return await response.json(); }; ``` ### 4. Отклик на оповещение ```javascript const respondToAlert = async (alertId, responseType, message, eta) => { const token = localStorage.getItem('access_token'); const response = await fetch(`http://192.168.0.103:8000/api/emergency/alerts/${alertId}/responses`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ response_type: responseType, // 'help_on_way', 'contacted_authorities', etc. message: message, eta_minutes: eta, location_sharing: true }) }); return await response.json(); }; ``` ## 📱 React Native компоненты ### SOS Button Component ```jsx import React, { useState } from 'react'; import { View, TouchableOpacity, Text, Alert } from 'react-native'; import Geolocation from '@react-native-community/geolocation'; const SOSButton = ({ onEmergencyCreated }) => { const [isCreating, setIsCreating] = useState(false); const handleSOSPress = () => { Alert.alert( 'Экстренная ситуация', 'Вы уверены, что хотите отправить SOS сигнал?', [ { text: 'Отмена', style: 'cancel' }, { text: 'SOS', style: 'destructive', onPress: createEmergencyAlert } ] ); }; const createEmergencyAlert = () => { setIsCreating(true); Geolocation.getCurrentPosition( async (position) => { try { const alert = await createEmergencyAlert( { latitude: position.coords.latitude, longitude: position.coords.longitude }, 'general', 'Экстренная помощь необходима!' ); onEmergencyCreated(alert); Alert.alert('Успешно', 'SOS сигнал отправлен'); } catch (error) { Alert.alert('Ошибка', 'Не удалось отправить SOS сигнал'); } setIsCreating(false); }, (error) => { Alert.alert('Ошибка', 'Не удалось получить местоположение'); setIsCreating(false); } ); }; return ( {isCreating ? 'Отправка...' : 'SOS'} ); }; ``` ### Nearby Alerts List ```jsx import React, { useEffect, useState } from 'react'; import { View, FlatList, Text, TouchableOpacity } from 'react-native'; const NearbyAlertsList = ({ userLocation }) => { const [alerts, setAlerts] = useState([]); const [loading, setLoading] = useState(false); useEffect(() => { if (userLocation) { loadNearbyAlerts(); } }, [userLocation]); const loadNearbyAlerts = async () => { setLoading(true); try { const nearbyAlerts = await findNearbyAlerts(userLocation); setAlerts(nearbyAlerts); } catch (error) { console.error('Ошибка загрузки оповещений:', error); } setLoading(false); }; const handleRespondToAlert = async (alertId) => { try { await respondToAlert(alertId, 'help_on_way', 'Еду на помощь!', 10); Alert.alert('Успешно', 'Ваш отклик отправлен'); loadNearbyAlerts(); // Обновить список } catch (error) { Alert.alert('Ошибка', 'Не удалось отправить отклик'); } }; const renderAlert = ({ item }) => ( {item.alert_type.toUpperCase()} 📍 {item.address || 'Адрес не указан'} 📏 {item.distance_km.toFixed(1)} км от вас 👥 Откликов: {item.responded_users_count} handleRespondToAlert(item.id)} > Помочь ); return ( Ближайшие оповещения {loading ? ( Загрузка... ) : ( item.id.toString()} refreshing={loading} onRefresh={loadNearbyAlerts} ListEmptyComponent={ Поблизости нет активных оповещений } /> )} ); }; ``` ## 🔄 Обновление местоположения в реальном времени ```javascript class LocationService { constructor() { this.watchId = null; this.lastUpdate = null; } startLocationTracking() { this.watchId = Geolocation.watchPosition( (position) => { this.updateLocation(position.coords); }, (error) => { console.error('Location error:', error); }, { enableHighAccuracy: true, distanceFilter: 10, // Обновлять при изменении на 10 метров interval: 30000, // Обновлять каждые 30 секунд } ); } async updateLocation(coords) { const now = Date.now(); // Не отправляем слишком часто if (this.lastUpdate && (now - this.lastUpdate) < 30000) { return; } try { const token = localStorage.getItem('access_token'); await fetch('http://192.168.0.103:8000/api/location/update', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ latitude: coords.latitude, longitude: coords.longitude, accuracy: coords.accuracy, speed: coords.speed, heading: coords.heading, timestamp: new Date().toISOString() }) }); this.lastUpdate = now; } catch (error) { console.error('Failed to update location:', error); } } stopLocationTracking() { if (this.watchId) { Geolocation.clearWatch(this.watchId); this.watchId = null; } } } ``` ## 🔔 Push уведомления ### Настройка Firebase (Android) / APNS (iOS) ```javascript import messaging from '@react-native-firebase/messaging'; class PushNotificationService { async requestPermission() { const authStatus = await messaging().requestPermission(); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { console.log('Push permissions granted'); await this.getToken(); } } async getToken() { try { const token = await messaging().getToken(); await this.registerToken(token); } catch (error) { console.error('Failed to get push token:', error); } } async registerToken(token) { const apiToken = localStorage.getItem('access_token'); await fetch('http://192.168.0.103:8000/api/notifications/register-token', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiToken}` }, body: JSON.stringify({ token: token, platform: Platform.OS, // 'ios' or 'android' app_version: '1.0.0' }); } setupForegroundHandler() { messaging().onMessage(async remoteMessage => { // Показать уведомление когда приложение активно Alert.alert( remoteMessage.notification.title, remoteMessage.notification.body ); }); } setupBackgroundHandler() { messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('Background message:', remoteMessage); }); } } ``` ## 🔐 Безопасность и шифрование ### Хранение токенов ```javascript import * as Keychain from 'react-native-keychain'; class SecureStorage { static async storeToken(token) { try { await Keychain.setInternetCredentials( 'women_safety_app', 'access_token', token ); } catch (error) { console.error('Failed to store token:', error); } } static async getToken() { try { const credentials = await Keychain.getInternetCredentials('women_safety_app'); if (credentials) { return credentials.password; } } catch (error) { console.error('Failed to get token:', error); } return null; } static async removeToken() { try { await Keychain.resetInternetCredentials('women_safety_app'); } catch (error) { console.error('Failed to remove token:', error); } } } ``` ### Шифрование местоположения ```javascript import CryptoJS from 'crypto-js'; class LocationEncryption { static encryptLocation(lat, lng, secretKey) { const locationData = JSON.stringify({ lat, lng, timestamp: Date.now() }); return CryptoJS.AES.encrypt(locationData, secretKey).toString(); } static decryptLocation(encryptedData, secretKey) { try { const bytes = CryptoJS.AES.decrypt(encryptedData, secretKey); const decryptedData = bytes.toString(CryptoJS.enc.Utf8); return JSON.parse(decryptedData); } catch (error) { console.error('Failed to decrypt location:', error); return null; } } } ``` ## 📊 Аналитика и мониторинг ### Отслеживание использования ```javascript class AnalyticsService { static trackEmergencyAlert(alertType, responseTime) { // Интеграция с аналитикой (Firebase Analytics, etc.) analytics().logEvent('emergency_alert_created', { alert_type: alertType, response_time_seconds: responseTime, timestamp: Date.now() }); } static trackUserResponse(alertId, responseType) { analytics().logEvent('emergency_response', { alert_id: alertId, response_type: responseType, timestamp: Date.now() }); } static trackLocationUpdate(accuracy) { analytics().logEvent('location_update', { accuracy_meters: accuracy, timestamp: Date.now() }); } } ``` ## 🧪 Тестирование API ### Unit тесты для API клиента ```javascript import { APIClient } from './APIClient'; describe('APIClient', () => { let client; beforeEach(() => { client = new APIClient('http://192.168.0.103:8000'); }); test('should login successfully', async () => { const result = await client.login('testuser', 'testpass'); expect(result.access_token).toBeDefined(); expect(result.token_type).toBe('bearer'); }); test('should create emergency alert', async () => { // Сначала авторизоваться await client.login('testuser', 'testpass'); const alert = await client.createAlert({ latitude: 55.7558, longitude: 37.6176, alert_type: 'general', message: 'Test emergency' }); expect(alert.id).toBeDefined(); expect(alert.alert_type).toBe('general'); expect(alert.status).toBe('active'); }); test('should get nearby alerts', async () => { await client.login('testuser', 'testpass'); const alerts = await client.getNearbyAlerts(55.7558, 37.6176, 5); expect(Array.isArray(alerts)).toBe(true); }); }); ``` ## 📈 Оптимизация производительности ### Кэширование данных ```javascript class CacheService { static cache = new Map(); static CACHE_DURATION = 5 * 60 * 1000; // 5 минут static set(key, data) { this.cache.set(key, { data, timestamp: Date.now() }); } static get(key) { const cached = this.cache.get(key); if (!cached) return null; if (Date.now() - cached.timestamp > this.CACHE_DURATION) { this.cache.delete(key); return null; } return cached.data; } static async getNearbyAlertsWithCache(lat, lng, radius) { const cacheKey = `nearby_${lat}_${lng}_${radius}`; let alerts = this.get(cacheKey); if (!alerts) { alerts = await findNearbyAlerts({ latitude: lat, longitude: lng }, radius); this.set(cacheKey, alerts); } return alerts; } } ``` Эти примеры покрывают все основные сценарии использования API в реальном мобильном приложении, включая безопасность, производительность и тестирование.