Makale

Expo için Yerel Öncelikli HealthKit ve Health Connect Köprüsü

Apple HealthKit ve Google Health Connect’i, arayüzde platform koşulları olmadan tek bir yeniden kullanılabilir React hook’u arkasında birleştirmek için bir tasarım deseni.

Expo için Yerel Öncelikli HealthKit ve Health Connect Köprüsü

Herkese merhaba! 👋 Çapraz platform bir React Native uygulamasında hiç sağlık, fitness veya yardımcı bir özellik geliştirmeyi denediyseniz acısını bilirsiniz: tek bir özellik seti yazmıyorsunuz, birbirinden tamamen ayrı iki ağır yerel ekosistemle uğraşıyorsunuz.

1. Başlangıç

iOS’ta olgun Apple HealthKit API’si var. Android’de ise eski Google Fit SDK’sının yerini alan, Google’ın birleşik API çerçevesi Health Connect var. Yeni uygulamam WaterPaw için su takibi mimarisini geliştirirken tamamen modüler bir çözüm istedim.

Platform koşullu kontrollerinin (Platform.OS === 'ios') arayüz katmanımı karıştırmasını istemedim. Kullanılabilirliği, izinleri ve veri çekmeyi tek bir çatı altında yöneten, soyut ve tekil bir özel React hook’u istedim. İşte yerel yapılandırmaları otomatik yönetmek için Expo Config Plugin’lerden yararlanarak bunları birleştirmek için kullandığım temiz tasarım deseni.

Önce, frontend’in hangi yerel platformda çalıştığını umursamaması için somut bir plan (interface) tanımladım:

export type HydrationData = {
  value: number; // in milliliters
  date: string;
};

export interface HealthBridge {
  isAvailable(): Promise<boolean>;
  requestPermissions(): Promise<boolean>;
  getHydrationData(date: Date): Promise<HydrationData[]>;
}

2. Somut Köprüler

Ardından tam uygulama ayrıntılarını yalıtılmış yerel sarmalayıcılara ayırdım.

  • iOS Sarmalayıcısı: Başlatılma durumunu kontrol etmek ve standart HealthKit izin matrislerini iletmek içinreact-native-health ile çalışır.
  • Android Sarmalayıcısı: Gerekli iki adımlı yürütme akışını (başlatma kontrolü ve ardından ayrı bir izin intent sözleşmesi) kullanarakreact-native-health-connect ile çalışır.

3. Hook: Dinamik Platform Dışa Aktarımı

Sihir, köprüyü platforma göre dinamik olarak dışa aktarırken gerçekleşir; bu da bileşenlerin tek bir özel hook’u çağırmasına olanak tanır:

import { Platform } from 'react-native';
import { iOSHealthBridge } from './iOSHealthBridge';
import { AndroidHealthBridge } from './AndroidHealthBridge';

const HealthAPI = Platform.OS === 'ios' ? iOSHealthBridge : AndroidHealthBridge;

export function useHydrationSync() {
  const syncData = async () => {
    const available = await HealthAPI.isAvailable();
    if (!available) return;

    const hasPermission = await HealthAPI.requestPermissions();
    if (hasPermission) {
      const records = await HealthAPI.getHydrationData(new Date());
      // Commit directly to a local-first store (e.g. AsyncStorage or Zustand)
    }
  };

  return { syncData };
}

4. Expo’daki Büyük Tuzak 💡

Her iki yerel paket de yoğun biçimde özelleştirilmiş yerel kod (Objective-C ve Kotlin) kullandığı için standart Expo Go içinde derlenmezler. Xcode veya Android Studio ile elle uğraşmadan bunu temiz biçimde aşmak için app.json içinde config plugin’leri tanımlamanız gerekir. Health Connect’in açıkça en az SDK 26 gerektirdiğini unutmayın:

{
  "expo": {
    "plugins": [
      ["react-native-health", { "NSHealthShareUsageDescription": "Sync your hydration records." }],
      ["expo-health-connect"],
      [
        "expo-build-properties",
        { "android": { "minSdkVersion": 26 } }
      ]
    ]
  }
}

Bunu güncelledikten sonra npx expo prebuild --clean çalıştırmak yerel üretimi otomatik olarak halleder.

Neden tüm bu zahmete giriyoruz?

Minimalist yardımcı uygulamalar geliştirirken performans ve sıfır sürtünme her şeydir. Bu mimariyle arayüz 60 FPS’te akıcı kalır, güncellemeler anlıktır ve yerel öncelikli olduğu için uygulama kullanıcının veri gizliliğine tamamen saygı gösterir. Üçüncü taraf sunucu yok, zorunlu hesap kaydı yok.

Bu yapısal mantığı, yeni yayınladığım WaterPaw içindeki akıllı hatırlatmaları ve maskot ilerleme sistemlerini güçlendirmek için kullandım!