You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 18.3调用fetchHistory获取HistoryTransaction时崩溃求助

问题原因

崩溃的核心是iOS 18.3强化了SwiftData历史记录的枚举校验逻辑:你的VideoPlacement枚举原本有queue成员,后来改名为queueNext并添加了原始值,但HistoryTransaction中还留存着旧的变更记录(比如之前设置placeVideosIn = .queue的操作)。iOS 18.3开始,解析这些历史记录时,SwiftData会严格检查枚举成员是否存在,找不到queue就触发致命错误。

手动修改现有模型的placeVideosIn值没用,因为崩溃触发在读取历史变更记录,而非当前模型数据——旧的历史条目依然存在,fetchHistory时还是会尝试解析废弃的枚举成员。

至于删除HistoryTransactions时偶尔丢失模型,这是操作不当导致的:如果你的删除逻辑没有精准过滤HistoryTransaction类型,可能误删了关联的模型对象;或者部分历史记录和模型的删除操作绑定,批量删除时连带删掉了模型。这不属于正常现象,是可以避免的。

解决方案

1. 临时安全清理问题历史记录

不要直接删除全部HistoryTransactions,而是精准过滤并删除涉及placeVideosIn属性的旧历史条目,避免误伤模型:

import SwiftData

func cleanupOldVideoPlacementHistory(in container: ModelContainer) {
    let context = ModelContext(container)
    // 只筛选涉及placeVideosIn属性变更的历史记录
    let fetchDescriptor = FetchDescriptor<HistoryTransaction>(
        predicate: #Predicate { transaction in
            transaction.changes.contains(where: { $0.propertyName == "placeVideosIn" })
        }
    )
    
    do {
        let problematicTransactions = try context.fetch(fetchDescriptor)
        problematicTransactions.forEach { context.delete($0) }
        try context.save()
        print("成功清理旧枚举相关的历史记录")
    } catch {
        print("清理历史记录失败:\(error.localizedDescription)")
    }
}

调用这个方法后,再执行fetchHistory就不会触发崩溃了。

2. 永久兼容方案:保留枚举旧成员作为别名

在VideoPlacement枚举中保留旧的queue成员,标记为废弃并映射到新的queueNext的原始值,让旧历史记录能被正常解析:

enum VideoPlacement: Int, Codable, PersistentEnum {
    case inbox = 0
    // 保留旧成员,映射到新的原始值,标记为废弃
    @available(*, deprecated, renamed: "queueNext")
    case queue = 1
    case queueNext = 1
    case nothing = 2
    case defaultPlacement = 3
    case queueLast = 4
}

这样,历史记录中的queue会被自动解析为queueNext,不会触发校验错误。等后续所有用户都完成版本更新(旧历史记录被自然清理后),再移除这个废弃的queue成员即可。

额外注意

  • 后续修改枚举时,尽量避免直接删除或重命名成员,优先采用添加新成员、标记旧成员废弃的方式,保证历史记录的兼容性。
  • 测试时,务必覆盖包含旧枚举值的历史记录场景,避免上线后出现类似崩溃。

内容的提问来源于stack exchange,提问作者fer0n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:17:41