统一账号作用域 Key 对齐 Android,新增缓存 schema 迁移清理旧数据,并同步更新相关模块与单元测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
9.8 KiB
9.8 KiB
AppStore 缓存 Key 升级对照
结论
- 旧线上工程与重构版工程的主应用 Bundle ID 均为
com.yuanzhixiang.suixinkan。通过 App Store 覆盖升级时,系统会保留原应用容器,因此旧版UserDefaults会继续存在。 - 本次升级策略为:强制重新登录、旧偏好全部重置、不迁移旧缓存。
- 新 Key 只对齐 Android 的业务作用域;iOS 统一使用
_作为分隔符,不复制 Android MMKV 历史实现中无分隔符拼接的写法。 - 本文中的“旧线上工程”为
/Users/hanqiu/Desktop/android_project/suixinkan_ios,“重构版工程”为/Users/hanqiu/Desktop/suixinkan。
Key 占位符
| 占位符 | 含义 |
|---|---|
O |
旧版将 [accountType, userId, storeId, scenicId] 中的非空值用 _ 拼接,再清洗非字母数字字符后得到的 accountKey |
P |
本次实施前重构版使用的 <userId>_<accountType> 账号前缀;用户 ID 为空时可能退化为 guest |
A |
本次实施后统一使用的 <accountType>_<userId> 账号前缀 |
S |
景区 ID(scenicId) |
T |
排队点位 ID(spotId) |
R |
角色编码(roleCode) |
suixinkan.session.v1是旧工程中真实存在的单个UserDefaultsKey,其值为 JSON Data。表格中的suixinkan.session.v1[token]等写法仅表示该 JSON 内的字段,不是独立的UserDefaultsKey。
新旧工程统一业务 Key 对照
| 业务数据 | 旧线上工程 Key | 重构版实施前 Key | 统一后的 Key | 升级处理 |
|---|---|---|---|---|
| 登录会话 | suixinkan.session.v1 JSON |
拆分为多个 key_in_* |
保持拆分结构 | 删除旧会话,强制登录 |
| Token | suixinkan.session.v1[token] |
key_in_token |
key_in_token |
首次升级清空 |
| 用户 ID | suixinkan.session.v1[userId] |
key_in_user_id |
key_in_user_id |
首次升级清空 |
| 用户名 | suixinkan.session.v1[userName] |
key_in_user_name |
key_in_user_name |
首次升级清空 |
| 头像 | suixinkan.session.v1[avatar] |
key_in_avatar |
key_in_avatar |
首次升级清空 |
| 手机号 | suixinkan.session.v1[phone] |
key_in_phone |
key_in_phone |
首次升级清空 |
| 账号类型 | suixinkan.session.v1[accountType] |
key_in_account_type |
key_in_account_type |
首次升级清空 |
| 账号类型显示名称 | suixinkan.session.v1[accountDisplayName] |
key_in_account_display_name |
key_in_account_display_name |
首次升级清空 |
| 角色 ID | suixinkan.session.v1[roleId] |
P_key_in_role_id |
A_key_in_role_id |
不迁移;当前仅用于 legacy 权限匹配兜底 |
| 角色编码 | 无独立 Key | key_in_role_code |
A_key_in_role_code |
改为账号作用域 |
| 角色名称 | suixinkan.session.v1[roleName] |
key_in_role_name |
A_key_in_role_name |
改为账号作用域 |
| 权限列表 | 无 | P_key_role_permission_list |
A_key_role_permission_list |
不迁移预发布数据 |
| 当前权限 | 无 | P_key_in_permission |
A_key_in_permission |
不迁移预发布数据 |
| 角色景区列表 | 无 | P_key_current_role_scenic_list |
A_key_current_role_scenic_list |
不迁移预发布数据 |
| 当前景区 ID | suixinkan.session.v1[scenicId] |
key_in_current_scenic_id |
A_key_in_current_scenic_id |
改为账号作用域 |
| 当前景区名称 | suixinkan.session.v1[scenicName] |
key_in_current_scenic_name |
A_key_in_current_scenic_name |
改为账号作用域 |
| 当前门店 ID | suixinkan.session.v1[storeId] |
key_in_current_store_id |
A_scenic_S_scenic_store_id |
改为账号+景区作用域 |
| 当前门店名称 | suixinkan.session.v1[storeName] |
无 | 不再持久化 | 删除旧值 |
| 常用菜单 | home.common.menu.uris |
P_role_R_common_uris |
A_role_R_common_uris |
不迁移旧菜单;仅统一作用域,Android 精确后缀不同 |
| 收款语音 | payment.voice.broadcast.enabled |
P_key_is_open_receive_voice |
A_key_is_open_receive_voice |
重置为默认值 |
| 在线状态 | 无 | P_key_online_status |
A_key_online_status |
改为账号作用域 |
| 上次位置上报时间 | 无 | P_key_last_location_report_time |
A_key_last_location_report_time |
改为账号作用域 |
| 定位提醒分钟数 | 无 | P_key_location_reminder_minutes |
A_key_location_reminder_minutes |
改为账号作用域 |
| 当前排队点位 ID | account_O_scenic_S_scenic_queue_selected_spot_id |
P__scenic_queue_punch_spot_id |
A_scenic_S_scenic_queue_punch_spot_id |
不迁移 |
| 当前排队点位名称 | account_O_scenic_S_scenic_queue_selected_spot_name |
P__scenic_queue_punch_spot_name |
A_scenic_S_spot_T_scenic_queue_punch_spot_name |
不迁移 |
| 排队播报备注 | account_O_scenic_S_scenic_queue_custom_tts_text_spot_T |
P__scenic_queue_remark |
A_scenic_S_spot_T_scenic_queue_remark |
不迁移 |
| 排队设置快照 | account_O_scenic_S_scenic_queue_settings_snapshot_spot_T |
P__scenic_queue_settings_snapshot |
A_scenic_S_spot_T_scenic_queue_settings_snapshot |
不迁移 |
| 排队预设语音 | account_O_scenic_S_scenic_queue_preset_voices_spot_T |
P__scenic_queue_preset_voices_v1 |
A_scenic_S_spot_T_scenic_queue_preset_voices_v1 |
不迁移 |
| 离线 TTS | 无 | P__scenic_queue_offline_tts_v1 |
A_scenic_S_scenic_queue_offline_tts_v1 |
默认值对齐 Android 为 true |
首次升级需要清理的旧 Key
已新增整型版本标记 suixinkan.cache.schema.version。当版本小于目标缓存版本时执行一次清理,全部清理完成后再写入目标版本,避免每次启动重复清空用户重新登录后产生的数据。
会话与推送
suixinkan.session.v1apns_device_tokenapns_uploaded_token
同时清空重构版预发布阶段可能存在的登录与账号字段,以确保升级后强制重新登录:
key_in_tokenkey_last_login_usernamekey_in_user_idkey_in_user_namekey_in_real_namekey_in_avatarkey_in_phonekey_in_account_typekey_in_account_display_namekey_in_role_idkey_in_role_codekey_in_role_namekey_in_current_scenic_idkey_in_current_scenic_namekey_in_current_store_id
key_privacy_agreement_accepted 是否清理应服从“旧偏好全部重置”的既定策略,因此本次也应清理。
同时清理早期重构实现可能写入的以下未分域业务字段:
key_role_permission_listkey_in_permissionkey_current_role_scenic_listkey_online_statuskey_last_location_report_timekey_location_reminder_minuteskey_is_open_receive_voice
首页与收款
home.common.menu.urishome.common.menu.android.baseline.v2home.routing.unknown.recordspayment.voice.broadcast.enabled
排队全局偏好
scenic_queue_tts_enabledscenic_queue_background_poll_enabledscenic_queue_selected_spot_idscenic_queue_selected_spot_namescenic_queue_custom_tts_textscenic_queue_photo_estimate_secondsscenic_queue_broadcast_interval_secondsscenic_queue_countdown_threshold_secondsscenic_queue_show_start_shooting_buttonscenic_queue_auto_call_ahead_countscenic_queue_quick_call_button_enabledscenic_queue_prepare_call_button_enabledscenic_queue_config_logsscenic_queue_settings_snapshotscenic_queue_preset_voices
排队动态缓存
清理符合以下已知格式的旧 Key,不应扩大为删除整个 UserDefaults domain:
account_O_scenic_S_scenic_queue_selected_spot_idaccount_O_scenic_S_scenic_queue_selected_spot_nameaccount_O_scenic_S_scenic_queue_custom_tts_text_spot_Taccount_O_scenic_S_scenic_queue_settings_snapshot_spot_Taccount_O_scenic_S_scenic_queue_preset_voices_spot_Tscenic_S_spot_T_scenic_queue_settings_snapshotscenic_S_scenic_queue_settings_snapshotscenic_S_spot_T_scenic_queue_preset_voices
重构版预发布缓存
清理使用旧 P 前缀的以下 Key 家族:
P_key_in_role_idP_key_role_permission_listP_key_in_permissionP_key_current_role_scenic_listP_key_online_statusP_key_last_location_report_timeP_key_location_reminder_minutesP_key_is_open_receive_voiceP_role_R_common_urisP__scenic_queue_punch_spot_idP__scenic_queue_punch_spot_nameP__scenic_queue_remarkP__scenic_queue_settings_snapshotP__scenic_queue_offline_tts_v1P__scenic_queue_preset_voices_v1
其中 P__scenic_queue_* 的双下划线来自当前 Key 生成器和自带前导下划线的后缀叠加,属于需要淘汰的错误格式。
不应清理的内容
- 禁止调用
removePersistentDomain(forName:)清空应用的整个UserDefaultsdomain,应只删除明确列出的 Key 和严格匹配的动态 Key。 - 不删除
Documents/CloudDownloads。该目录可能包含用户主动下载的文件,不属于普通缓存。 - 不删除 SDK 缓存、图片缓存或其他未列入本次升级范围的用户文件。
- 不做旧
suixinkan.session.v1、排队设置、常用菜单或收款偏好的解码与迁移。
发布前备注
- 旧线上版本为
1.0.1 (2);当前覆盖升级版本已设置为1.1.4 (1010401)。 - 重构版当前未保留旧工程的 APNs entitlement、远程通知后台能力、回调和设备 Token 上传流程。该问题不是缓存 Key 修改,但若线上仍需要推送,发布前必须单独恢复并验证。清理
apns_device_token与apns_uploaded_token后,恢复推送时应重新绑定设备 Token。 Application Support/suixinkan/cloud_transfer_tasks.json当前为全账号共享文件,存在账号切换后读取其他账号任务的风险。该问题不是UserDefaultsKey 迁移的一部分,应作为独立发布风险处理。- 本方案已在重构版中实施:应用首次创建
AppStore时按suixinkan.cache.schema.version执行一次定向清理,并切换到表格中的统一 Key;不删除未列入范围的UserDefaults或用户文件。