Swift项目Core Data存储数据失败,收藏页无法展示存储内容问题求助
问题排查与修复方案
你代码中存在多个逻辑错误导致Core Data存储和展示失效,具体问题和修复方案如下:
核心问题列表
- 保存时未绑定对应cell的数据:点击cell按钮拿到行号后,没有取出当前行对应的Article数据,原来的全局存储变量
newsTitle/newsAuthor等始终为nil,导致保存的都是空数据 - isSaved全局逻辑错误:该变量仅在页面加载时判断是否有过存储记录,只要有过任意存储就永久为true,后续点击所有cell的保存按钮都会直接跳过保存逻辑
- 收藏页漏设tableView数据源:
FavouriteNewsViewController中两次设置了delegate,漏了dataSource赋值,就算有数据也不会渲染列表 - 页面加载时错误执行空保存:
viewDidLoad中直接调用了saveNews(),此时所有数据变量都是nil,会生成无效的空存储记录 - 收藏页加载数据后未刷新UI:
loadSavedNews拿到存储数据后没有调用列表刷新方法,UI不会更新 - 缺描述字段存储逻辑:Core Data模型的
desc字段没有对应Article的description属性赋值,保存后该字段为空
修复代码
1. 替换ViewController中的点击保存逻辑,删除无效全局变量
你可以直接删掉原代码中全局的newsTitle/newsAuthor/urlString/newsDate/isSaved变量,同时删除viewDidLoad中的saveNews()调用,替换didTapCellButton方法如下:
@objc func didTapCellButton(sender: UIButton) { let index = sender.tag // 校验行号有效性 guard articles.indices.contains(index) else { return } let targetArticle = articles[index] // 配置查询请求,用新闻url作为唯一标识判断是否已保存,避免重复存储 let fetchRequest: NSFetchRequest<SavedNews> = SavedNews.fetchRequest() fetchRequest.predicate = NSPredicate(format: "url == %@", targetArticle.url ?? "") do { let existItems = try context.fetch(fetchRequest) // 仅未保存过的新闻才执行存储 if existItems.isEmpty { let savedNews = SavedNews(context: context) savedNews.title = targetArticle.title savedNews.author = targetArticle.author ?? "未知作者" savedNews.publishedAt = targetArticle.publishedAt savedNews.url = targetArticle.url savedNews.desc = targetArticle.description ?? "暂无描述" // 持久化存储 try context.save() print("新闻保存成功") } else { print("该新闻已在收藏列表中") } } catch { print("存储操作失败:\(error.localizedDescription)") } }
2. 修复FavouriteNewsViewController的代理设置与数据刷新逻辑
修改viewDidLoad中的代理配置:
override func viewDidLoad() { super.viewDidLoad() // 修正代理设置,补上dataSource favTableView.delegate = self favTableView.dataSource = self favTableView.register(UINib(nibName: S.FavouriteCell.favouriteCell, bundle: nil), forCellReuseIdentifier: S.FavouriteCell.favouriteCellIdentifier) loadSavedNews() }
修改loadSavedNews方法,加载完数据后刷新列表:
func loadSavedNews() { let request: NSFetchRequest<SavedNews> = SavedNews.fetchRequest() do { savedNews = try context.fetch(request) // 主线程刷新UI DispatchQueue.main.async { self.favTableView.reloadData() } } catch { print("加载收藏数据失败:\(error.localizedDescription)") } }
内容的提问来源于stack exchange,提问作者dextermikles
相关产品推荐
相关产品推荐

