如何使用Core Data在iOS两个视图控制器间实现新闻数据保存与展示
iOS新闻应用Core Data收藏功能实现方案
1. 自定义单元格点击回调配置
自定义新闻单元格内新增闭包属性,用于按钮点击事件的回调,避免selector无法绑定对应新闻数据的问题:
// 自定义NewsTableViewCell类 class NewsTableViewCell: UITableViewCell { @IBOutlet weak var saveButton: UIButton! // 按钮点击回调闭包 var saveButtonTapped: (() -> Void)? override func awakeFromNib() { super.awakeFromNib() // 给保存按钮绑定点击事件 saveButton.addTarget(self, action: #selector(saveButtonClicked), for: .touchUpInside) } @objc private func saveButtonClicked() { saveButtonTapped?() } }
2. 主视图控制器单元格配置与保存触发
在主视图控制器的tableView(_:cellForRowAt:)方法中,给每个单元格的回调闭包赋值,拿到当前行对应的新闻数据后执行Core Data保存逻辑:
// 主视图控制器cellForRowAt方法 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "NewsCell", for: indexPath) as! NewsTableViewCell let currentNews = newsList[indexPath.row] // 配置单元格其他内容... // 绑定保存按钮点击逻辑 cell.saveButtonTapped = { [weak self] in self?.saveNewsToLocal(news: currentNews) } return cell }
3. Core Data保存逻辑实现
首先确认Core Data模型中已创建对应收藏新闻的实体(示例实体名为SavedNews,属性与你的新闻模型属性一一对应),新增保存方法:
private func saveNewsToLocal(news: NewsModel) { guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } let context = appDelegate.persistentContainer.viewContext // 查重逻辑,避免重复保存同一条新闻 let fetchRequest: NSFetchRequest<SavedNews> = SavedNews.fetchRequest() fetchRequest.predicate = NSPredicate(format: "id == %@", news.id as CVarArg) do { let existingResults = try context.fetch(fetchRequest) guard existingResults.isEmpty else { // 已存在该收藏,可自行添加重复提示逻辑 return } // 新建Core Data实体对象赋值 let savedItem = SavedNews(context: context) savedItem.id = news.id savedItem.title = news.title savedItem.content = news.content savedItem.coverImageUrl = news.coverImageUrl savedItem.publishTime = news.publishTime // 其他属性按需赋值 try context.save() } catch { print("Core Data保存失败:\(error.localizedDescription)") } }
4. 收藏视图控制器数据加载
在收藏视图控制器的生命周期方法中触发Core Data数据拉取,刷新列表:
class FavoritesViewController: UIViewController { @IBOutlet weak var tableView: UITableView! private var favoritesList: [SavedNews] = [] override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) fetchFavoritesData() } private func fetchFavoritesData() { guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } let context = appDelegate.persistentContainer.viewContext let fetchRequest: NSFetchRequest<SavedNews> = SavedNews.fetchRequest() // 可按需添加排序规则,示例按保存时间倒序 fetchRequest.sortDescriptors = [NSSortDescriptor(key: "saveTime", ascending: false)] do { favoritesList = try context.fetch(fetchRequest) tableView.reloadData() } catch { print("收藏数据读取失败:\(error.localizedDescription)") } } } // 收藏页UITableView数据源方法实现 extension FavoritesViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return favoritesList.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "FavoriteCell", for: indexPath) as! FavoriteTableViewCell let item = favoritesList[indexPath.row] // 配置收藏单元格内容 cell.titleLabel.text = item.title cell.contentLabel.text = item.content // 其他属性赋值 return cell } }
异常排查点
- 确认保存按钮的
isUserInteractionEnabled属性为true,没有被上层视图遮挡点击 - 确认Core Data实体的属性名、类型与代码中赋值的参数完全一致,避免拼写错误
- 若保存后收藏页未及时刷新,可新增通知监听:保存成功后发送
NSNotification.Name("SaveSuccess")通知,收藏页监听该通知触发数据刷新
内容的提问来源于stack exchange,提问作者dextermikles
相关产品推荐
相关产品推荐

