feat: 支持 expo 44 版本

This commit is contained in:
2025-09-11 23:00:24 +08:00
parent 0cb7e67b5e
commit dfe9506a7a
10 changed files with 4070 additions and 2233 deletions

View File

@@ -19,7 +19,6 @@ import { createWaterRecordAction } from '@/store/waterSlice';
import { MoodNotificationHelpers, NutritionNotificationHelpers } from '@/utils/notificationHelpers'; import { MoodNotificationHelpers, NutritionNotificationHelpers } from '@/utils/notificationHelpers';
import { clearPendingWaterRecords, syncPendingWidgetChanges } from '@/utils/widgetDataSync'; import { clearPendingWaterRecords, syncPendingWidgetChanges } from '@/utils/widgetDataSync';
import React from 'react'; import React from 'react';
import RNExitApp from 'react-native-exit-app';
import { DialogProvider } from '@/components/ui/DialogProvider'; import { DialogProvider } from '@/components/ui/DialogProvider';
import { ToastProvider } from '@/contexts/ToastContext'; import { ToastProvider } from '@/contexts/ToastContext';
@@ -138,7 +137,7 @@ function Bootstrapper({ children }: { children: React.ReactNode }) {
}; };
const handlePrivacyDisagree = () => { const handlePrivacyDisagree = () => {
RNExitApp.exitApp(); // RNExitApp.exitApp();
}; };
return ( return (

View File

@@ -4,7 +4,7 @@ require File.join(File.dirname(`node --print "require.resolve('react-native/pack
require 'json' require 'json'
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
ENV['RCT_NEW_ARCH_ENABLED'] = '0' if podfile_properties['newArchEnabled'] == 'false' ENV['RCT_NEW_ARCH_ENABLED'] = '1' if podfile_properties['newArchEnabled'] == 'false'
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1' platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'

File diff suppressed because it is too large Load Diff

View File

@@ -7,5 +7,7 @@
<key>NSExtensionPointIdentifier</key> <key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string> <string>com.apple.widgetkit-extension</string>
</dict> </dict>
<key>RCTNewArchEnabled</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@@ -216,6 +216,7 @@
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */, 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
7996A12D2E6FB82300371142 /* Embed Foundation Extensions */, 7996A12D2E6FB82300371142 /* Embed Foundation Extensions */,
CD8A4C026AF644A41E91C9E8 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@@ -351,11 +352,16 @@
inputFileListPaths = ( inputFileListPaths = (
); );
inputPaths = ( inputPaths = (
"$(SRCROOT)/.xcode.env",
"$(SRCROOT)/.xcode.env.local",
"$(SRCROOT)/digitalpilates/digitalpilates.entitlements",
"$(SRCROOT)/Pods/Target Support Files/Pods-digitalpilates/expo-configure-project.sh",
); );
name = "[Expo] Configure project"; name = "[Expo] Configure project";
outputFileListPaths = ( outputFileListPaths = (
); );
outputPaths = ( outputPaths = (
"$(SRCROOT)/Pods/Target Support Files/Pods-digitalpilates/ExpoModulesProvider.swift",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
@@ -376,7 +382,6 @@
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/PurchasesHybridCommon/PurchasesHybridCommon.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/PurchasesHybridCommon/PurchasesHybridCommon.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/QCloudCOSXML/QCloudCOSXML.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle",
@@ -401,7 +406,6 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/PurchasesHybridCommon.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/PurchasesHybridCommon.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QCloudCOSXML.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle",
@@ -421,6 +425,24 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-digitalpilates/Pods-digitalpilates-resources.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-digitalpilates/Pods-digitalpilates-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
CD8A4C026AF644A41E91C9E8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-digitalpilates/Pods-digitalpilates-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-digitalpilates/Pods-digitalpilates-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@@ -684,7 +706,7 @@
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
USE_HERMES = false; USE_HERMES = true;
}; };
name = Debug; name = Debug;
}; };
@@ -741,7 +763,7 @@
); );
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
USE_HERMES = false; USE_HERMES = true;
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
name = Release; name = Release;

View File

@@ -57,20 +57,22 @@
<string>应用需要访问您的健康数据(步数、能量消耗、心率变异性等)以展示运动统计和压力分析。</string> <string>应用需要访问您的健康数据(步数、能量消耗、心率变异性等)以展示运动统计和压力分析。</string>
<key>NSHealthUpdateUsageDescription</key> <key>NSHealthUpdateUsageDescription</key>
<string>应用需要更新您的健康数据(体重信息)以记录您的健身进度。</string> <string>应用需要更新您的健康数据(体重信息)以记录您的健身进度。</string>
<key>NSMicrophoneUsageDescription</key>
<string>应用需要使用麦克风进行语音识别,将您的语音转换为文字记录饮食信息。</string>
<key>NSPhotoLibraryAddUsageDescription</key> <key>NSPhotoLibraryAddUsageDescription</key>
<string>应用需要写入相册以保存拍摄的体态照片(可选)。</string> <string>应用需要写入相册以保存拍摄的体态照片(可选)。</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>应用需要访问相册以选择您的体态照片用于AI测评。</string> <string>应用需要访问相册以选择您的体态照片用于AI测评。</string>
<key>NSUserNotificationsUsageDescription</key> <key>NSSpeechRecognitionUsageDescription</key>
<string>应用需要发送通知以提醒您喝水和站立活动。</string> <string>应用需要使用语音识别功能来转换您的语音为文字,帮助您快速记录饮食信息。</string>
<key>NSMicrophoneUsageDescription</key>
<string>应用需要使用麦克风进行语音识别,将您的语音转换为文字记录饮食信息。</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>应用需要使用语音识别功能来转换您的语音为文字,帮助您快速记录饮食信息。</string>
<key>NSUserActivityTypes</key> <key>NSUserActivityTypes</key>
<array> <array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
</array> </array>
<key>NSUserNotificationsUsageDescription</key>
<string>应用需要发送通知以提醒您喝水和站立活动。</string>
<key>RCTNewArchEnabled</key>
<true/>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>processing</string> <string>processing</string>

3240
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,8 @@
"lint": "expo lint" "lint": "expo lint"
}, },
"dependencies": { "dependencies": {
"@expo/vector-icons": "^14.1.0", "@expo/ui": "~0.2.0-beta.0",
"@expo/vector-icons": "^15.0.2",
"@react-native-async-storage/async-storage": "^2.2.0", "@react-native-async-storage/async-storage": "^2.2.0",
"@react-native-community/datetimepicker": "^8.4.4", "@react-native-community/datetimepicker": "^8.4.4",
"@react-native-masked-view/masked-view": "^0.3.2", "@react-native-masked-view/masked-view": "^0.3.2",
@@ -22,64 +23,61 @@
"@react-navigation/elements": "^2.3.8", "@react-navigation/elements": "^2.3.8",
"@react-navigation/native": "^7.1.6", "@react-navigation/native": "^7.1.6",
"@reduxjs/toolkit": "^2.8.2", "@reduxjs/toolkit": "^2.8.2",
"@sentry/react-native": "^7.0.1", "@sentry/react-native": "~6.20.0",
"@types/lodash": "^4.17.20", "@types/lodash": "^4.17.20",
"cos-js-sdk-v5": "^1.6.0", "cos-js-sdk-v5": "^1.6.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"expo": "53.0.22", "expo": "^54.0.1",
"expo-apple-authentication": "~7.2.4", "expo-apple-authentication": "~8.0.6",
"expo-background-task": "~1.0.6", "expo-background-task": "~1.0.6",
"expo-blur": "~14.1.5", "expo-blur": "~15.0.6",
"expo-camera": "^16.1.11", "expo-camera": "~17.0.7",
"expo-constants": "~17.1.7", "expo-constants": "~18.0.8",
"expo-font": "~13.3.2", "expo-font": "~14.0.7",
"expo-haptics": "~14.1.4", "expo-haptics": "~15.0.6",
"expo-image": "~2.4.0", "expo-image": "~3.0.7",
"expo-image-picker": "~16.1.4", "expo-image-picker": "~17.0.7",
"expo-linear-gradient": "^14.1.5", "expo-linear-gradient": "~15.0.6",
"expo-linking": "~7.1.7", "expo-linking": "~8.0.7",
"expo-notifications": "~0.32.10", "expo-notifications": "~0.32.10",
"expo-quick-actions": "^5.0.0", "expo-quick-actions": "^5.0.0",
"expo-router": "~5.1.5", "expo-router": "~6.0.0",
"expo-splash-screen": "~0.30.10", "expo-splash-screen": "~31.0.8",
"expo-status-bar": "~2.2.3", "expo-status-bar": "~3.0.7",
"expo-symbols": "~0.4.5", "expo-symbols": "~1.0.6",
"expo-system-ui": "~5.0.11", "expo-system-ui": "~6.0.7",
"expo-task-manager": "~14.0.6", "expo-task-manager": "~14.0.6",
"expo-web-browser": "~14.2.0", "expo-web-browser": "~15.0.6",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lottie-react-native": "^7.3.4", "lottie-react-native": "^7.3.4",
"react": "19.0.0", "react": "19.1.0",
"react-dom": "19.0.0", "react-dom": "19.1.0",
"react-native": "0.79.5", "react-native": "0.81.4",
"react-native-cos-sdk": "^1.2.1",
"react-native-device-info": "^14.0.4", "react-native-device-info": "^14.0.4",
"react-native-exit-app": "^2.0.0", "react-native-gesture-handler": "~2.28.0",
"react-native-gesture-handler": "~2.24.0",
"react-native-health": "^1.19.0", "react-native-health": "^1.19.0",
"react-native-image-viewing": "^0.2.2", "react-native-image-viewing": "^0.2.2",
"react-native-markdown-display": "^7.0.2", "react-native-markdown-display": "^7.0.2",
"react-native-modal-datetime-picker": "^18.0.0", "react-native-modal-datetime-picker": "^18.0.0",
"react-native-popover-view": "^6.1.0", "react-native-popover-view": "^6.1.0",
"react-native-purchases": "^9.2.2", "react-native-purchases": "^9.2.2",
"react-native-reanimated": "~3.17.4", "react-native-reanimated": "~4.1.0",
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "5.4.0", "react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.11.1", "react-native-screens": "~4.16.0",
"react-native-svg": "^15.12.1", "react-native-svg": "^15.12.1",
"react-native-toast-message": "^2.3.3", "react-native-toast-message": "^2.3.3",
"react-native-web": "~0.20.0", "react-native-web": "^0.21.0",
"react-native-webview": "13.13.5", "react-native-webview": "13.15.0",
"react-native-wheel-picker-expo": "^0.5.4", "react-native-wheel-picker-expo": "^0.5.4",
"react-redux": "^9.2.0", "react-redux": "^9.2.0"
"@expo/ui": "~0.1.1-alpha.10"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
"@types/react": "~19.0.10", "@types/react": "~19.1.12",
"eslint": "^9.25.0", "eslint": "^9.25.0",
"eslint-config-expo": "~9.2.0", "eslint-config-expo": "~10.0.0",
"typescript": "~5.8.3" "typescript": "~5.9.2"
}, },
"private": true "private": true
} }

View File

@@ -1,6 +1,5 @@
import { COS_BUCKET, COS_REGION, buildPublicUrl } from '@/constants/Cos'; import { COS_BUCKET, COS_REGION, buildPublicUrl } from '@/constants/Cos';
import { api } from '@/services/api'; import { api } from '@/services/api';
import Cos from 'react-native-cos-sdk';
type ServerCosToken = { type ServerCosToken = {
tmpSecretId: string; tmpSecretId: string;
@@ -89,25 +88,25 @@ export async function uploadToCos(options: UploadOptions): Promise<{ key: string
// 初始化 react-native-cos-sdk一次 // 初始化 react-native-cos-sdk一次
if (!rnInitialized) { if (!rnInitialized) {
await Cos.initWithSessionCredentialCallback(async () => { // await Cos.initWithSessionCredentialCallback(async () => {
// SDK 会在需要时调用该回调,我们返回当前的临时密钥 // // SDK 会在需要时调用该回调,我们返回当前的临时密钥
return { // return {
tmpSecretId: cred.credentials.tmpSecretId, // tmpSecretId: cred.credentials.tmpSecretId,
tmpSecretKey: cred.credentials.tmpSecretKey, // tmpSecretKey: cred.credentials.tmpSecretKey,
sessionToken: cred.credentials.sessionToken, // sessionToken: cred.credentials.sessionToken,
startTime: cred.startTime, // startTime: cred.startTime,
expiredTime: cred.expiredTime, // expiredTime: cred.expiredTime,
} as any; // } as any;
}); // });
const serviceConfig = { region, isDebuggable: true, isHttps: true } as any; // const serviceConfig = { region, isDebuggable: true, isHttps: true } as any;
await Cos.registerDefaultService(serviceConfig); // await Cos.registerDefaultService(serviceConfig);
const transferConfig = { // const transferConfig = {
forceSimpleUpload: false, // forceSimpleUpload: false,
enableVerification: true, // enableVerification: true,
divisionForUpload: 2 * 1024 * 1024, // divisionForUpload: 2 * 1024 * 1024,
sliceSizeForUpload: 1 * 1024 * 1024, // sliceSizeForUpload: 1 * 1024 * 1024,
} as any; // } as any;
rnTransferManager = await Cos.registerDefaultTransferManger(serviceConfig, transferConfig); // rnTransferManager = await Cos.registerDefaultTransferManger(serviceConfig, transferConfig);
rnInitialized = true; rnInitialized = true;
} }

View File

@@ -1,34 +0,0 @@
declare module 'react-native-cos-sdk' {
export type SessionCredential = {
tmpSecretId: string;
tmpSecretKey: string;
sessionToken: string;
startTime?: number;
expiredTime?: number;
};
export function initWithSessionCredentialCallback(cb: () => Promise<SessionCredential> | SessionCredential): Promise<void> | void;
export function registerDefaultService(config: { region: string; isHttps?: boolean; isDebuggable?: boolean }): Promise<any>;
export function registerDefaultTransferManger(
serviceConfig: { region: string; isHttps?: boolean; isDebuggable?: boolean },
transferConfig: {
forceSimpleUpload?: boolean;
enableVerification?: boolean;
divisionForUpload?: number;
sliceSizeForUpload?: number;
}
): Promise<any>;
export function getDefaultTransferManger(): any;
export default {
initWithSessionCredentialCallback,
registerDefaultService,
registerDefaultTransferManger,
getDefaultTransferManger,
};
}