更新 shenyan-app: HealthKit+WeatherKit+冰箱贴+pare+三区布局

- HealthKitBridge.m: 自定义原生模块,心率/步数/睡眠采集
- WeatherKitBridge.swift/m: 天气模块,当前+每日+每小时预报
- pare.py: 身体数据陡度监控,阈值告警→inbox+冰箱贴
- cyberboss: 5-20分钟随机唤醒,pare→decide→push
- 冰箱贴: 纸质感卡片,黑字多级透明度,独立输入框
- 首页三区无视觉布局: 左门/中记录/右冰箱
- 端口3003→3004(VS Code占用)
- 聊天屏锚定底部滚动

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 19:14:32 +08:00
parent d07d50dde5
commit 2a053ab88e
12 changed files with 791 additions and 184 deletions

View File

@@ -0,0 +1,80 @@
import Foundation
import WeatherKit
import CoreLocation
@available(iOS 16.0, *)
@objc(WeatherKitBridge)
class WeatherKitBridge: NSObject {
let service = WeatherService.shared
@objc
static func requiresMainQueueSetup() -> Bool { return false }
@available(iOS 16.0, *)
@objc
func getWeather(_ lat: Double, lon: Double, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let location = CLLocation(latitude: lat, longitude: lon)
Task {
do {
let weather = try await service.weather(for: location)
let current = weather.currentWeather
let result: [String: Any] = [
"temperature": current.temperature.value,
"humidity": current.humidity * 100,
"condition": current.condition.rawValue,
"pressure": current.pressure.value,
"uvIndex": current.uvIndex.value,
"windSpeed": current.wind.speed.value as Any,
"isDaylight": current.isDaylight,
"visibility": current.visibility.value as Any
]
resolve(result)
} catch {
reject("weatherkit", error.localizedDescription, error)
}
}
}
@available(iOS 16.0, *)
@objc
func getDailyForecast(_ lat: Double, lon: Double, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let location = CLLocation(latitude: lat, longitude: lon)
Task {
do {
let weather = try await service.weather(for: location)
let daily = weather.dailyForecast.prefix(3).map { day in
return [
"high": day.highTemperature.value,
"low": day.lowTemperature.value,
"condition": day.condition.rawValue,
"precipitationChance": day.precipitationChance * 100
] as [String : Any]
}
resolve(daily)
} catch {
reject("weatherkit", error.localizedDescription, error)
}
}
}
@objc
func getHourlyForecast(_ lat: Double, lon: Double, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
let location = CLLocation(latitude: lat, longitude: lon)
Task {
do {
let weather = try await service.weather(for: location)
let hourly = weather.hourlyForecast.prefix(6).map { hour in
return [
"temperature": hour.temperature.value,
"condition": hour.condition.rawValue,
"precipitationChance": hour.precipitationChance * 100,
"date": hour.date.timeIntervalSince1970 * 1000
] as [String : Any]
}
resolve(hourly)
} catch {
reject("weatherkit", error.localizedDescription, error)
}
}
}
}