@appeeky/expo-healthkit (英语)
苹果公司 卫生科 和 Android 数据 健康连接 页:1 博览 并基于 展览模块 API。 。 。 .
两个平台都有一个JavaScript API. 您通过 Apple HealthKit 类型标识符(HKQuantityTypeIdentifierStepCount,.),查询或保存样本,本地地层在iOS和Android上的HealthKit上与HealthKit交谈.
| iOS系统 | 机器人 | |
|---|---|---|
| 后端 | 卫生科 | 健康连接 |
| 应用程序代码 | 相同的识别标志和方法 | 相同的识别标志和方法 |
| 可用性 | isAvailable() 当健康 Kit 出现时 | isAvailable() 当健康连接安装时 |
- 展览 SDK 53+ / 新建筑(在 SDK 57 上测试)
- 基于承诺类型Script API
- HealthKit 应享权利配置插件 财务报告和审定财务报表 健康连接权限( E)
minSdk(第26段) - iOS 16.4+,Android 8+ (API 26+). 网络报告
isAvailable() === false
健康数据 API 无法在 Expo Go 中运行 。 使用开发建设( U)
npx expo run:ios或者说npx expo run:android) (中文(简体) ).
所需经费
- 曝光 SDK 53 或 后期及 a 发展 (不是博览会)
- iOS 16.4+, 物理 iPhone 或模拟器, 在 App ID 上启用了 HealthKit 能力 苹果开发者门户网站
- Android 8+ 与 维基月球 健康连接 (安装在Android 14+)
QQ 安装
npx expo install @appeeky/expo-healthkit
从GitHub, 如果你正在跟踪 main 释放前:
npx expo install github:appeeky/expo-healthkit
添加配置插件到 app.json 编号 : app.config.ts数字 :
{
"expo": {
"plugins": [
[
"@appeeky/expo-healthkit",
{
"healthSharePermission": "Allow $(PRODUCT_NAME) to read your health data",
"healthUpdatePermission": "Allow $(PRODUCT_NAME) to write health data",
"isBackgroundDeliveryEnabled": true
}
]
],
"ios": {
"bundleIdentifier": "com.example.app"
}
}
}
然后重建本地密码:
npx expo prebuild --clean
npx expo run:ios
# or
npx expo run:android
启用 卫生科 在苹果开发者门户网站上的 App ID 能力。 插件将权限写入生成的 Xcode 工程; 仍然必须允许该捆绑的ID .
在Android上安装 健康连接 如果操作系统还没有包含它(在Android 14+上构建). 插件宣布健康连接权限( 默认情况下所有映射类型; 以 healthConnectPermissions)和 提高 minSdk 改为26个。 模块本身的表单宣布无,因此一个不运行配置插件的赤裸回放原生应用程序必须添加 android.permission.health.* uses-permission 它需要的条目 AndroidManifest.xml 自己来.
快速启动
import * as HealthKit from '@appeeky/expo-healthkit';
if (!HealthKit.isAvailable()) {
return;
}
await HealthKit.requestAuthorization({
toRead: [
HealthKit.QuantityType.stepCount,
HealthKit.QuantityType.heartRate,
HealthKit.CategoryType.sleepAnalysis,
HealthKit.WorkoutType.workout,
],
toShare: [HealthKit.QuantityType.stepCount],
});
const today = new Date();
today.setHours(0, 0, 0, 0);
const steps = await HealthKit.queryStatistics({
type: HealthKit.QuantityType.stepCount,
unit: HealthKit.Unit.count,
from: today,
to: new Date(),
options: HealthKit.StatisticsOption.cumulativeSum,
});
const heartRate = await HealthKit.queryQuantitySamples({
type: HealthKit.QuantityType.heartRate,
unit: HealthKit.Unit.countPerMinute,
from: today,
to: new Date(),
limit: 20,
ascending: false,
});
• API
* 可用性和权限
| 方法 | 页:1 |
|---|---|
isAvailable() | true iOS 当健康 Kit 存在时, Android 当健康连接安装时 |
getSupportedTypes() | 此平台可以提供标识符 。 呆子,别急 iOS:HealthKit在这个OS上解决什么;Android:健康连接映射;web: [] |
getUnsupportedTypes(identifiers) | 子集为 identifiers 此平台无法提供 |
requestAuthorization({ toRead, toShare, includeBackgroundRead }) | 显示系统权限表(HealthKit或Health Connect). includeBackgroundRead 添加健康连接 READ_HEALTH_DATA_IN_BACKGROUND (仅Android;需要插件的) isHealthConnectBackgroundReadEnabled(中文(简体) ) |
getAuthorizationStatus(type) | iOS:用于 写入 类型。 Android: 反映已获得的健康连接读取或写取权限 |
getRequestStatusForAuthorization({ toRead, toShare }) | 您是否还需要提示 |
getGrantedPermissions() | 安卓:获准 android.permission.health.* 字符串。 iOS: 此应用程序可能存在的标识符 写入 ——"健康Kit"不披露读取补助 |
requestPermissions(permissions) | Android: 请求原始 android.permission.health.* 字符串,用指定的子集解决。 iOS: 抛出 ERR_HEALTHKIT_UNSUPPORTED |
revokeAllPermissions() | Android: in-app"断开健康连接". 撤销程序在应用程序结束后生效,Android可能立即终止;在此之前 getGrantedPermissions() 仍在列出补助金。 iOS: 抛出 ERR_HEALTHKIT_UNSUPPORTED (健康Kit没有撤销) |
在iOS上,读取授权故意不透明: getAuthorizationStatus 返回时 notDetermined 编号 : sharingDenied 已经 没有 表示用户被屏蔽读取.
ERR_HEALTHKIT_UNSUPPORTED 是 iOS 镜像 ERR_HEALTH_CONNECT_UNSUPPORTED: 方法存在于两个平台上, 因此应用程序代码不需要 Platform.OS 叉子,一个不能这样做的后端也这么说.
抽样和统计
| 方法 | 用于 | |
|---|---|---|
| ❤️ | queryQuantitySamples({ type, unit, from, to, limit, ascending }) | 心率,体重,葡萄糖,.. |
| 😴 | queryCategorySamples({ type, from, to, limit, ascending }) | 睡觉,注意会议,.. |
| 🏃 | queryWorkouts({ from, to, limit, ascending, activityType }) | 劳动 |
| 🫀 | queryElectrocardiograms({ from, to, limit, ascending, includeVoltage }) | ECG样本. 除非 includeVoltage: true |
| 🔴 | queryActivitySummaries({ from, to }) | 移动/ 练习/ 站出环 |
| 🏥 | queryClinicalRecords({ type, from, to, limit, ascending }) | FHIR临床记录. 需求 isClinicalDataEnabled |
| 👂 | queryAudiograms({ from, to, limit, ascending }) | 听力测试声克 |
| 📍 | queryWorkoutRoute({ workoutUUID }) | 解决的全球定位系统位置 |
| 🩺 | queryCorrelations({ type, from, to, limit, ascending }) | 血压和食物的相关性 |
| 💓 | queryHeartbeatSeries({ from, to, limit, ascending, includeBeats }) | 用于HRV的打到打系列 |
| 📈 | queryStatistics({ type, unit, from, to, options }) | 总数/分/最大/平均 |
| 📅 | queryStatisticsCollection({ type, unit, from, to, interval, options }) | 每日(或小时)桶 |
| 🔄 | queryAnchored({ type, unit, from, to, limit, anchor }) | 递增同步 。 存储 anchor把它传回来 hasMore |
limit 默认为 H健康Kit 的无限查询 。 接受日期 Date 或 ISO-8601 字符串。 单位是健康 Kit 单位字符串(count, (中文(简体) ), count/min, (中文(简体) ), kcal, (中文(简体) ), kg, (中文(简体) ), m, (中文(简体) ), %,并导出为 Unit。 。 。 .
源过滤器
上述每个查询(活动摘要和解决路线除外)都接受 sources 财务报告和审定财务报表 excludeSources双取iOS捆绑标识符/Android包名; 'self' 内 excludeSources 这是应用程序。 同步时用它跳过自己的写法 :
const heartRate = await HealthKit.queryQuantitySamples({
type: HealthKit.QuantityType.heartRate,
unit: HealthKit.Unit.countPerMinute,
from: today,
limit: 100,
excludeSources: ['self'],
});
const watchOnly = await HealthKit.queryWorkouts({
sources: ['com.apple.health'],
});
过滤器在本地运行, 在此之前 limit在两个平台上: limit: 100 与 excludeSources: ['self'] 返回其他应用程序所写的100个最新样本,而不是100行减去你的。 在iOS上,它们编译到一个 HKQuery.predicateForObjects(from:) 上游; 在 Android 上 sources 是请求的 dataOriginFilter 财务报告和审定财务报表 excludeSources 在计算限额之前,将适用于每一页. queryStatistics 编号 : queryStatisticsCollection android 支持软件 sources 仅限; excludeSources 掷出 ERR_HEALTH_CONNECT_UNSUPPORTED。 。 。 . queryAnchored 过滤器添加了样本;删除时没有来源,总是返回.
焦虑同步
queryAnchored 返回时 { added, deleted, anchor, hasMore }。应用页面,坚持 anchor,然后在 hasMore 这是真的。 处理 added 以上调键入 uuid:样本可以到达两次.
let anchor = await loadAnchor(); // null on first sync
let hasMore = true;
while (hasMore) {
const page = await HealthKit.queryAnchored({ type, unit, limit: 500, anchor });
await applyPage(page.added, page.deleted);
anchor = page.anchor;
hasMore = page.hasMore;
await saveAnchor(anchor);
}
- 锚是不透明的标志,而不是时间戳. 在iOS上它是存档的
HKQueryAnchor; 在Android上,它包裹一个"健康连接"(Health Connection)更改符(加上第一次同步时的一页符). 它在平台之间,在应用程序之间,或者从另一个库中——一个被保存在@kingstinct/react-native-healthkit或者说react-native-health-connect,或基于时间戳光标的ISO日期,在此不是有效的符号。 坚持每个平台和类型,当从另一个光标迁移时,首先anchor: null并解开uuid。 。 。 . - Android 第一次同步. 由于没有主播,现有记录在以下页面中阅读:
limit记录(心率记录可以扩大到许多样本;否)limit阅读所有的一切在一个呼叫中。 更改符号在第一页之前取出,所以写作或删除的记录在之后随着更改而到达——hasMore在读完这些之前要保持真实. - Android,已过期或被拒绝的主播. Health Connect将其更改日志保存了30天,所以一个符号在更长的过期时间内被使用.
queryAnchored然后掷出ERR_HEALTH_CONNECT_ANCHOR_EXPIRED而不是返回三角洲: 空隙期间的删除已丢失, 因此以anchor: null并核对您的副本 与全文。 “健康连接”报告一个符号,它不会以同样的方式识别(例如从另一个图书馆中识别一个)。 一个畸形锚抛出ERR_INVALID_ANCHOR,其他的“健康连接”错误被抛出。 重新启动的读取限于最近30天, 除非用户同意READ_HEALTH_DATA_HISTORY(与toRead) (中文(简体) ). - iOS. (原始内容存档于2017-10-12). 健康Kit没有说是否还有更多的结果,所以
hasMore当一个页面满了时为真;下一个呼叫可能空出。 不属于 Base64 的字符串被视为“ 无锚” , 并再次运行初始抓取( 只有 base64 字符串不是HKQueryAnchor存档拒绝).
ECG,活性环,临床记录,音频克,工作GPS路线,心跳系列,以及关联性都不是数量/类别/工作样本. 请求匹配标识符在 toRead数字 :
await HealthKit.requestAuthorization({
toRead: [
HealthKit.ElectrocardiogramType.electrocardiogram,
HealthKit.ActivitySummaryType.activitySummary,
HealthKit.ClinicalType.allergyRecord,
HealthKit.AudiogramType.audiogram,
HealthKit.WorkoutType.workout,
HealthKit.SeriesType.workoutRoute,
HealthKit.SeriesType.heartbeat,
HealthKit.CorrelationType.bloodPressure,
HealthKit.CorrelationType.food,
],
});
const rings = await HealthKit.queryActivitySummaries({ from: today });
const [workout] = await HealthKit.queryWorkouts({ limit: 1 });
const routes = workout
? await HealthKit.queryWorkoutRoute({ workoutUUID: workout.uuid })
: [];
const pressure = await HealthKit.queryCorrelations({
type: HealthKit.CorrelationType.bloodPressure,
limit: 20,
});
临床也读作需要 isClinicalDataEnabled: true 在配置插件上.
++ 写/ 删除
await HealthKit.saveQuantitySample({
type: HealthKit.QuantityType.stepCount,
unit: HealthKit.Unit.count,
value: 100,
startDate: new Date(Date.now() - 60_000),
endDate: new Date(),
});
await HealthKit.saveCategorySample({
type: HealthKit.CategoryType.sleepAnalysis,
value: HealthKit.SleepAnalysisValue.asleepCore,
startDate,
endDate,
});
await HealthKit.saveWorkout({
activityType: HealthKit.WorkoutActivityType.running,
startDate,
endDate,
energyBurned: 400,
energyBurnedUnit: HealthKit.Unit.kilocalorie,
distance: 5000,
distanceUnit: HealthKit.Unit.meter,
});
await HealthKit.saveCorrelation({
type: HealthKit.CorrelationType.bloodPressure,
startDate: new Date(),
objects: [
{
type: HealthKit.QuantityType.bloodPressureSystolic,
unit: HealthKit.Unit.millimeterOfMercury,
value: 120,
},
{
type: HealthKit.QuantityType.bloodPressureDiastolic,
unit: HealthKit.Unit.millimeterOfMercury,
value: 80,
},
],
});
await HealthKit.deleteObjects({
type: HealthKit.QuantityType.stepCount,
uuid,
});
* 特征
getBiologicalSex(), (中文(简体) ), getBloodType(), (中文(简体) ), getDateOfBirth(), (中文(简体) ), getFitzpatrickSkinType(), (中文(简体) ), getWheelchairUse()。这些是只读的健康Kit特性;包括匹配 CharacteristicType 内 toRead。 。 。 .
* 背景更新
await HealthKit.observe([HealthKit.QuantityType.stepCount]);
const subscription = HealthKit.addUpdateListener(async ({ type }) => {
// Re-query that type. Return a promise: iOS keeps the app alive and holds
// the HealthKit completion handler until it settles (~25s cap).
await syncSteps();
});
await HealthKit.enableBackgroundDelivery(
HealthKit.QuantityType.stepCount,
HealthKit.UpdateFrequency.hourly
);
useHealthKitUpdates() 是一个反应钩 围绕同一事件.
背景交付需要 isBackgroundDeliveryEnabled: true 在配置插件和HealthKit背景模式上.
杀机重启. 传入类型 observe 以当地方式坚持下去。 当iOS在"健康Kit"交付的背景中重新启动应用程序时,观察者查询会重新注册在 didFinishLaunching (通过一个博览会AppDelegate订阅者),在JS跑步时靴前. 送货要排队,直到JS打电话 addUpdateListener,然后发送。 在模块范围(或root组件的早期)中注册您的收听器, 因此它存在于冷启动时; getObservedTypes() 告诉你什么已经被观察到. clearObservers() 停止和忘记他们.
苹果极限. 步骤计数、距离、能量、锻炼/立体时间和类似活动类型最多 每小时一次 不论 UpdateFrequency;心率,睡眠,锻炼和身体测量没有被封顶. 每个寄件都得到~30 s的背景时间;如果听者没有完成,则库以25 s完成. 模拟器从未为HealthKit重启被杀死的应用程序——在一个设备上的测试.
调试. 原生原木位于 expo-healthkit os_log 子系统 (restore, (中文(简体) ), delivery, (中文(简体) ), complete reason=js|timeout) (中文(简体) ). 带设备测试配方的完整指南 : .cursor/skills/expo-healthkit/background-delivery.md。 。 。 .
缩写符
传递 Apple 的原始标识字符串 。 为自动完成提供了命名常数;如果HealthKit知道这些常数,未知的识别符仍然有效.
HealthKit.QuantityType.stepCount
// 'HKQuantityTypeIdentifierStepCount'
HealthKit.queryQuantitySamples({
type: 'HKQuantityTypeIdentifierStepCount',
unit: 'count',
});
App代码应该在两个平台上继续使用Apple标识字符串. 见 跨平台 何为“健康连接”地图、何为只使用iOS的地图,以及如何处理这些API Platform.OS 叉来.
* 跨平台
JavaScript总是说健康Kit. 你从来没有通过健康连接 记录类名称从应用代码。 本地层选择后端 :
flowchart LR
App["App JS<br/>QuantityType.stepCount"] --> API["@appeeky/expo-healthkit"]
API --> iOS["iOS<br/>HealthKit"]
API --> Android["Android<br/>Health Connect"]
(步骤、心率、睡眠、锻炼、体重、血压、营养.) 同一方法和标识符 在两个平台上。 在 Android 中跳过未映射的标识符 requestAuthorization,所以一个不支持的类型和一个空的看起来相似;首先询问:
const missing = HealthKit.getUnsupportedTypes([
HealthKit.QuantityType.vo2Max,
HealthKit.QuantityType.appleExerciseTime,
]);
// Android: ['HKQuantityTypeIdentifierAppleExerciseTime'] — say "not on this phone", not "no data"
在Androids上调用只使用苹果的方法 ERR_HEALTH_CONNECT_UNSUPPORTED 而不是要求 if (Platform.OS === 'ios') 每个查询中.
通过抓取该代码来隐藏只使用苹果的用户界面 :
try {
const rings = await HealthKit.queryActivitySummaries({ from: today });
} catch (error) {
if (error instanceof Error && 'code' in error && error.code === 'ERR_HEALTH_CONNECT_UNSUPPORTED') {
return;
}
throw error;
}
两者都有用
| 区域 | 标识符/方法 |
|---|---|
| 活动 | QuantityType.stepCount,行走/跑步/骑行/摇摆/轮椅相距, flightsClimbed, (中文(简体) ), pushCount, (中文(简体) ), activeEnergyBurned, (中文(简体) ), basalEnergyBurned |
| 心脏 | heartRate, (中文(简体) ), restingHeartRate, (中文(简体) ), heartRateVariabilitySDNN, (中文(简体) ), vo2Max, (中文(简体) ), oxygenSaturation, (中文(简体) ), respiratoryRate |
| 体质 | bodyMass, (中文(简体) ), height, (中文(简体) ), bodyFatPercentage, (中文(简体) ), leanBodyMass, (中文(简体) ), bodyTemperature, (中文(简体) ), bloodGlucose |
| 血压 | CorrelationType.bloodPressure 加上静脉/静脉量 |
| 营养 | CorrelationType.food, (中文(简体) ), dietaryWater,其他 HKQuantityTypeIdentifierDietary* 类型。 食物关联 HKFoodType 元数据映射到 NutritionRecord.name |
| 睡觉 | CategoryType.sleepAnalysis |
| 劳动 | queryWorkouts 编号 : saveWorkout (单位:千美元)WorkoutActivityType 健康连接活动类型) |
| 合计数 | queryStatistics, (中文(简体) ), queryStatisticsCollection, (中文(简体) ), queryAnchored |
| 写作 | saveQuantitySample, (中文(简体) ), saveCategorySample, (中文(简体) ), saveCorrelation, (中文(简体) ), deleteObjects |
仅限iOS
这些掷出 ERR_HEALTH_CONNECT_UNSUPPORTED 安卓号 健康连接没有等效( 或者还没有稳定的映射) :
| API 密码 | 为什么 |
|---|---|
queryElectrocardiograms | 苹果观察 ECG |
queryActivitySummaries | 移动/ 练习/ 站出环 |
queryClinicalRecords | FHIR 健康记录 |
queryAudiograms | 听力测试图 |
queryWorkoutRoute | 解决全球定位系统多线 |
queryHeartbeatSeries | 击败系列 |
getBiologicalSex, (中文(简体) ), getBloodType, (中文(简体) ), getDateOfBirth, (中文(简体) ), getFitzpatrickSkinType, (中文(简体) ), getWheelchairUse | 健康知识特征 |
observe, (中文(简体) ), getObservedTypes, (中文(简体) ), enableBackgroundDelivery | 健康Kit观察员查询/背景介绍 |
行为差异
| iOS系统 | 机器人 | |
|---|---|---|
| 后端 | 卫生科 | 健康连通(connect-client (第1.1段) |
isAvailable() | 健康知识 | 安装了健康连接(安装在Android 14+上;否则健康连接应用) |
| 读取权限 | 苹果会 没有 披露读取补助金; getGrantedPermissions 仅列出书面补助金 | getAuthorizationStatus 反映已获得的读取或写取健康连接; getGrantedPermissions 返回原始权限字符串 |
| 撤销 | 无(revokeAllPermissions 掷出 ERR_HEALTHKIT_UNSUPPORTED(中文(简体) ) | revokeAllPermissions() |
| 背景为: | 观察员询问/背景介绍 | requestAuthorization({ includeBackgroundRead: true }) 加插件的颜色 isHealthConnectBackgroundReadEnabled |
未映射类型 requestAuthorization | 如果HealthKit认识他们,就转发 | 跳过 |
| 历史窗口 | 任何年龄的样本 | 经常是最后一个 30天时间 除非用户也允许历史访问( SDK 请求它) |
| 焦虑同步 | HKQueryAnchor (不透明字符串) | 页面首先同步,然后健康连接更改(opaque string). 抛出过期的令牌 ERR_HEALTH_CONNECT_ANCHOR_EXPIRED 看到了吗 焦虑同步。不要重用安卓上的iOS锚 |
| 人力资源 | (原始内容存档于2017-10-21). SDNN. 样品携带 statistic: 'sdnn' | 在同一条上映到健康连接RMSD heartRateVariabilitySDNN 标识符——不是相同的统计。 样品携带 statistic: 'rmssd';在将两者组合在一起之前,先在其中分出 |
| 解决GPS | queryWorkoutRoute | 不支持 |
minSdk | iOS 16.4 (中文(简体) ) | API 26(插件加高) |
执行 没有 每个平台的分叉绘图查询 。 只有当您需要不同的用户界面时,才需要纯苹果功能.
XQ配置插件
| Prop | 默认 | 目的 |
|---|---|---|
healthSharePermission | "Allow $(PRODUCT_NAME) to read your health data" | NSHealthShareUsageDescription |
healthUpdatePermission | "Allow $(PRODUCT_NAME) to write health data" | NSHealthUpdateUsageDescription |
healthClinicalRecordsPermission | 临床默认 | 使用时 isClinicalDataEnabled 真实 |
isBackgroundDeliveryEnabled | false | 保健设备背景分娩权利 |
isClinicalDataEnabled | false | health-records 访问 |
healthConnectPrivacyPolicyUrl | —— 说 | 在健康连接许可理由屏幕上显示 |
healthConnectPermissions | 每个权限 模块地图(47, 包括. READ_HEALTH_DATA_HISTORY(中文(简体) ) | 健康连接 uses-permission 要声明的条目. READ_STEPS 或者说 android.permission.health.READ_STEPS设定时, 仅限 这些声明 |
isHealthConnectBackgroundReadEnabled | false | 声明 READ_HEALTH_DATA_IN_BACKGROUND 页:1 requestAuthorization({ includeBackgroundRead: true }) |
插件还设置 android.minSdkVersion 至 26 (健康连接层),除非项目已经使用更高的值.
插件为 仅限 设置健康连接权限; 模块本身 AndroidManifest.xml 无。 Play Console 请求您为每个已声明的“健康连接”数据类型说明理由, 权限表显示用户的完整列表, 因此将其缩小为您所查询的内容 :
["@appeeky/expo-healthkit", { "healthConnectPermissions": ["READ_STEPS", "READ_HEART_RATE", "READ_SLEEP", "READ_HEALTH_DATA_HISTORY"] }]
您未声明权限而查询的类型已跳过 requestAuthorization 并读作空. HEALTH_CONNECT_PERMISSIONS (从插件导出)是默认列表.
设置权限字符串到 false 以跳过写入 Info.plist 密钥( 如果您自己管理) .
QQ 示例应用程序
cd example
npm install
npx expo run:ios
# or
npx expo run:android
举例来说,是一个 Expo SDK 57 的应用软件,可以自动将这个模块连接到 iOS和Android 软件它不会在博览会去工作.
代理技能
编码代理(Cursor,Claude Code,Copilot等)应加载被捆绑的技能.
复制 .cursor/skills/expo-healthkit/ 输入您的应用 .cursor/skills/expo-healthkit/ (或代理技能文件夹):
| 文件 | 是什么探员得到的 |
|---|---|
SKILL.md | 何时使用哪个查询、认证规则和插件旗 |
reference.md | 方法签名、单位、标识符 |
examples.md | 复制纸流(步骤、睡眠、环、血压、食物) |
该技能告诉代理通过iOS和Android上一个查询/保存 API,将Apple标识字符串传递给代理,请求其中的每一个类型 toRead,并在斯威夫特,克特林,或插件更改后重建本地代码.
* 释放
随后的版本 铸造推进到 main 带有 常规武器委员会 运行 .github/workflows/release.yml: 颠倒 package.json,更新 CHANGELOG.md,GitHub 释放,以及 npm publish。 。 。 .
| 提交 | npm 颠倒 |
|---|---|
fix: … | 补丁( n)0.1.0 → 0.1.1(中文(简体) ) |
feat: … | 未成年人(0.1.0 → 0.2.0(中文(简体) ) |
feat!: … 或者说 BREAKING CHANGE: 体内 | 主要(0.1.0 → 1.0.0(中文(简体) ) |
docs:, (中文(简体) ), chore:, (中文(简体) ), ci:, (中文(简体) ), test: | 无释放 |
Squash- commerce PRs 所以合并承诺( 或 PR 标题) 以 fix: 编号 : feat:。 。 。 . chore: 财务报告和审定财务报表 ci: 不发表.
npm通过 GitHub 动作发布 值得信赖的出版 (无) NPM_TOKEN) (中文(简体) ). 一次性设置: 软件包设置 ~ 信任的出版商 ~ GitHub Actions, profile appeeky/expo-healthkit,工作流程文件名 release.yml,并允许 npm publish (不仅有舞台出版).
捐款
欢迎提出问题和拉动请求。 捐款按下列方式发放许可证: PolyForm 盾牌 1.0.0。 。 。 .
检查
中央情报局 main 每一个公关都运行 出字、排字、简讯和 npm pack 内容检查( e).github/workflows/ci.yml) (中文(简体) ). 在打开 PR 之前, 在本地运行相同的 :
npm ci
npm run lint
npm run typecheck
npm test -- --watchAll=false
npm run test:coverage
npm test 在 TTY 上打开 Jest 监视模式。 过 --watchAll=false (如CI所言)单跑. test:coverage 写入 HTML 报告到 coverage/ 并且必须保持绿色,用于测试已经覆盖的 JavaScript(src/identifiers.ts, (中文(简体) ), src/errors.ts, (中文(简体) ), src/dates.ts) (中文(简体) ).
测试什么
| 变动 | 预期覆盖范围 |
|---|---|
| 识别器、出错、日期助手、公共JS类型 | 在 src/__tests__/保留 npm run test:coverage 过 |
| 配置插件 | 类型检查 plugin/如果你们增加纯洁的助手,你们就把贾斯特放在他们旁边 |
| Kotlin 健康连接绘图 | 更新 跨平台 图表 财务报告和审定财务报表 .cursor/skills/expo-healthkit/。在带有“健康连接”的Android设备上运行示例 |
| 快速卫生设备 | 同样的技能/README更新. 在模拟器或具有健康Kit功能的设备上运行示例 |
| 示例UI | cd example && npx expo run:ios 编号 : npx expo run:android. API不运行于博览会 |
本地健康Kit / 健康连接无法在节点运行 。 设备或模拟验证是斯威夫特和克特林的覆盖. 不添加 Platform.OS 分支在 example/ 用于已经映射的类型.
本土重建
在斯威夫特,克特林,或插件编辑后,Metro重载是不够的:
npx expo prebuild --clean
npx expo run:ios
# or
npx expo run:android
文档
如果公共 API 或 Android 映射改变, 更新 README.md 财务报告和审定财务报表 .cursor/skills/expo-healthkit/ (单位:千美元)SKILL.md, (中文(简体) ), reference.md, (中文(简体) ), examples.md)在同一公关中. CHANGELOG.md 从常规承诺释放后产生.
隐私
健康数据会留在设备上 除非你的应用程序上传 只请求所需的类型,解释iOS使用字符串中的原因,在Play Console中宣布匹配的"健康连接"数据类型,并遵循"苹果健康Kit"和"谷歌健康连接"审查准则. Android的读取往往限于过去30天,除非用户也给予历史访问权.
许可证
PolyForm 盾牌 1.0.0。见 LICENSE 全部条件.
你个 能够 在您自己的 Expo / React Introduction apps 中安装和使用此 SDK, 包括商业产品 .
你个 无法 复制此 SDK 并出售、出版或以其他方式提供一个与之相竞争的 HealthKit / Health Connect 库.