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

iOS中保存FCM通知数据:哪种存储方式最适合?

适配FCM通知存储的最佳方案选择

结论

CoreData是最适配你需求的存储方案,其次是自定义文件存储(FileManager),UserDefaults不推荐用于这个场景。

各方案分析

1. UserDefaults

  • 不适配的原因:
    • UserDefaults本质是plist文件,仅适合存储小量、简单的配置类数据(比如开关状态、用户偏好设置),不适合存储大量列表型数据。如果通知数量增多,会导致读写性能下降,甚至阻塞主线程。
    • 虽然支持持久化和删除,但对列表数据的增删改查需要手动处理数组的序列化/反序列化,代码繁琐且容易出错。比如每次新增通知都要取出旧数组、添加新元素、再存回去,删除操作同理,还要额外处理结构体的Codable转换逻辑。

2. CoreData

  • 适配的原因:
    • 原生支持持久化存储,APP被杀死后数据不会丢失。
    • 内置增删改查操作,针对TableView展示场景,可直接通过NSFetchedResultsController绑定数据,自动处理列表更新(包括删除后的UI刷新),代码更简洁高效。
    • 你的通知是带三个字符串属性的结构体,能轻松映射成CoreData的实体(Entity),每个属性对应实体字段,无需复杂转换。
    • 后续如果需要扩展通知数据结构(比如添加时间戳、已读状态),CoreData能快速适配,扩展性强。

3. FileManager(自定义文件存储)

  • 可选但不如CoreData便捷:
    • 可以把通知数组序列化为JSON或Plist文件,通过FileManager读写到沙盒目录,也能实现持久化和删除。
    • 但需要手动处理文件读写、序列化/反序列化、线程安全(避免同时读写文件),还要自行实现列表的增删逻辑,代码量远大于CoreData。
    • 仅适合数据量极小且不想引入CoreData的场景,对于需要TableView展示和频繁删除的需求,没有CoreData高效。

CoreData实现示例

  1. 创建CoreData实体NotificationRecord,添加三个字符串属性(比如title、content、sender),可额外添加createdAt属性用于排序。
  2. 收到FCM通知时,创建实体实例并保存:
let context = persistentContainer.viewContext
let newRecord = NotificationRecord(context: context)
newRecord.title = notification.title
newRecord.content = notification.body
newRecord.sender = notification.sender
newRecord.createdAt = Date()
do {
    try context.save()
} catch {
    print("保存通知失败: \(error)")
}
  1. 使用NSFetchedResultsController绑定TableView数据,自动处理更新:
let fetchRequest: NSFetchRequest<NotificationRecord> = NotificationRecord.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
try? fetchedResultsController.performFetch()
  1. 删除指定通知时,直接操作CoreData上下文:
let record = fetchedResultsController.object(at: indexPath)
context.delete(record)
do {
    try context.save()
} catch {
    print("删除通知失败: \(error)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:52:21