UNPKG

react-native-healthkit-bridge

Version:

A comprehensive React Native bridge for Apple HealthKit with TypeScript support, advanced authorization, and flexible data queries

241 lines (240 loc) 10.6 kB
import { HealthKitBridge } from '../core/HealthKitBridge'; import { QuantityTypeIdentifier, HealthKitUnit } from '../types/healthkit.types'; /** * 📊 EXAMPLE: Complete Health Data Flow * * This example shows how to: * 1. Check authorization for specific data * 2. Request authorization only when needed * 3. Fetch data only for authorized types * 4. Handle errors and authorization status */ export class HealthDataWorkflowExample { constructor() { this.bridge = new HealthKitBridge(); } /** * 📋 EXAMPLE 1: Check and Get Steps Data */ async getStepsData() { var _a; console.log('👣 Checking steps data...'); try { // 1. Check authorization const authStatus = await this.bridge.getAuthorizationStatus([ QuantityTypeIdentifier.StepCount ]); const stepsAuth = authStatus[0]; console.log('🔐 Authorization status for steps:', stepsAuth); // 2. If not authorized, request if ((stepsAuth === null || stepsAuth === void 0 ? void 0 : stepsAuth.status) !== 'sharingAuthorized') { console.log('🔄 Requesting authorization for steps...'); await this.bridge.requestSelectiveAuthorization([QuantityTypeIdentifier.StepCount], []); // Check again const newAuthStatus = await this.bridge.getAuthorizationStatus([QuantityTypeIdentifier.StepCount]); if (((_a = newAuthStatus[0]) === null || _a === void 0 ? void 0 : _a.status) !== 'sharingAuthorized') { return { authorized: false, data: 0, message: 'Authorization denied for steps' }; } } // 3. Fetch data console.log('✅ Steps authorized! Fetching data...'); const stepsData = await this.bridge.getQuantitySamplesForDays(QuantityTypeIdentifier.StepCount, HealthKitUnit.count, 7); const totalSteps = stepsData.reduce((acc, item) => acc + (item.value || 0), 0); console.log('👣 Total steps (7 days):', totalSteps); return { authorized: true, data: totalSteps, message: 'Data retrieved successfully' }; } catch (error) { console.error('❌ Error getting steps data:', error); return { authorized: false, data: 0, message: `Error: ${error}` }; } } /** * 📋 EXAMPLE 2: Complete Flow for Multiple Types */ async getHealthDashboard() { var _a; console.log('📊 Loading health dashboard...'); const healthMetrics = [ { type: QuantityTypeIdentifier.StepCount, unit: HealthKitUnit.count, name: 'Steps' }, { type: QuantityTypeIdentifier.HeartRate, unit: HealthKitUnit.beatsPerMinute, name: 'Heart Rate' }, { type: QuantityTypeIdentifier.ActiveEnergyBurned, unit: HealthKitUnit.kilocalories, name: 'Active Energy' }, { type: QuantityTypeIdentifier.DistanceWalkingRunning, unit: HealthKitUnit.meters, name: 'Distance' }, { type: QuantityTypeIdentifier.AppleExerciseTime, unit: HealthKitUnit.minutes, name: 'Exercise Time' } ]; const results = {}; for (const metric of healthMetrics) { try { // 1. Check authorization const authStatus = await this.bridge.getAuthorizationStatus([metric.type]); const isAuthorized = ((_a = authStatus[0]) === null || _a === void 0 ? void 0 : _a.status) === 'sharingAuthorized'; if (isAuthorized) { console.log(`✅ ${metric.name} authorized, fetching data...`); // 2. Fetch data const data = await this.bridge.getQuantitySamplesForDays(metric.type, metric.unit, 1 // Today ); const total = data.reduce((acc, item) => acc + (item.value || 0), 0); results[metric.name] = { authorized: true, value: total, unit: metric.unit, message: 'Data retrieved successfully' }; console.log(`📊 ${metric.name}: ${total} ${metric.unit}`); } else { console.log(`❌ ${metric.name} not authorized`); results[metric.name] = { authorized: false, value: 0, unit: metric.unit, message: 'Not authorized' }; } } catch (error) { console.error(`❌ Error fetching ${metric.name}:`, error); results[metric.name] = { authorized: false, value: 0, unit: metric.unit, message: `Error: ${error}` }; } } return results; } /** * 📋 EXAMPLE 3: Check and Request Smart Authorization */ async requestAuthorizationForTypes(types) { console.log('🔐 Checking authorization for types:', types); try { // 1. Check current status const authStatus = await this.bridge.getAuthorizationStatus(types); console.log('📋 Current status:', authStatus); // 2. Separate by status const authorizedTypes = authStatus .filter(item => item.status === 'sharingAuthorized') .map(item => item.identifier); const deniedTypes = authStatus .filter(item => item.status === 'sharingDenied') .map(item => item.identifier); const notDeterminedTypes = authStatus .filter(item => item.status === 'notDetermined' || item.status === 'unknown') .map(item => item.identifier); console.log('✅ Already authorized:', authorizedTypes); console.log('❌ Denied:', deniedTypes); console.log('❓ Not determined:', notDeterminedTypes); // 3. If there are denied types, show instructions if (deniedTypes.length > 0) { console.log('⚠️ Some types were denied. Go to Settings > Privacy > Health to authorize manually.'); } // 4. Request authorization only for not determined types if (notDeterminedTypes.length > 0) { console.log('🔄 Requesting authorization for:', notDeterminedTypes); const authSuccess = await this.bridge.requestSelectiveAuthorization(notDeterminedTypes, []); if (authSuccess) { console.log('✅ Authorization requested successfully!'); // Check again const newAuthStatus = await this.bridge.getAuthorizationStatus(notDeterminedTypes); const newlyAuthorized = newAuthStatus .filter(item => item.status === 'sharingAuthorized') .map(item => item.identifier); console.log('🎉 New authorized types:', newlyAuthorized); return { success: true, authorizedTypes: [...authorizedTypes, ...newlyAuthorized], deniedTypes, message: `Authorization granted for: ${newlyAuthorized.join(', ')}` }; } else { console.log('❌ Failed to request authorization'); return { success: false, authorizedTypes, deniedTypes, message: 'Failed to request authorization' }; } } // 5. If all are already authorized return { success: true, authorizedTypes, deniedTypes, message: 'All types are already authorized' }; } catch (error) { console.error('❌ Error checking authorization:', error); return { success: false, authorizedTypes: [], deniedTypes: [], message: `Error: ${error}` }; } } /** * 📋 EXAMPLE 4: Complete Health Data Flow */ async getCompleteHealthData() { console.log('🚀 Starting complete health data flow...'); try { // 1. Define required types const requiredTypes = [ QuantityTypeIdentifier.StepCount, QuantityTypeIdentifier.HeartRate, QuantityTypeIdentifier.ActiveEnergyBurned, QuantityTypeIdentifier.DistanceWalkingRunning, QuantityTypeIdentifier.AppleExerciseTime ]; // 2. Check and request authorization const authResult = await this.requestAuthorizationForTypes(requiredTypes); if (!authResult.success) { console.log('❌ Authorization failed:', authResult.message); return { success: false, data: null, message: authResult.message }; } // 3. Fetch data for authorized types const healthData = await this.getHealthDashboard(); console.log('🎉 Complete flow finished!'); console.log('📊 Health data:', healthData); return { success: true, data: healthData, message: 'Data loaded successfully' }; } catch (error) { console.error('❌ Error in complete flow:', error); return { success: false, data: null, message: `Error: ${error}` }; } } } /** * 📋 HOW TO USE: * * ```typescript * const example = new HealthDataWorkflowExample(); * * // Get steps data * const stepsResult = await example.getStepsData(); * * // Check and request authorization for specific types * const authResult = await example.requestAuthorizationForTypes([ * QuantityTypeIdentifier.StepCount, * QuantityTypeIdentifier.HeartRate * ]); * * // Get complete dashboard * const dashboardData = await example.getHealthDashboard(); * * // Complete flow * const completeResult = await example.getCompleteHealthData(); * ``` */