ios - 如何从一个视图控制器保存数据并使用核心数据在另一个视图控制器中显示
问题描述
我需要帮助解决一个问题core data
。我有一个带有两个视图控制器的新闻应用程序。在main view controller
我正在自定义单元格的表格视图中加载新闻数据。在这里,我有一个button, on which should I tap and save news to another view controller
. 它现在看起来如何:它看起来如何所以当我们tap on this blue button, it should save news from the cell and display on second view controller
. 我创建了一个core data model
这样的:核心数据模型这是代码my first view controller
:
import UIKit
import SafariServices
import CoreData
class ViewController: UIViewController, UISearchBarDelegate, UpdateTableViewDelegate {
@IBOutlet weak var pecodeTableView: UITableView!
private var articles = [News]()
// private var viewModels = [NewsTableViewCellViewModel]()
private var viewModel = NewsListViewModel()
var newsTitle: String?
var newsAuthor: String?
var newsDesc: String?
var urlString: String?
var newsDate: String?
private let searchVC = UISearchController(searchResultsController: nil)
var selectedRow = Int()
override func viewDidLoad() {
super.viewDidLoad()
pecodeTableView.delegate = self
pecodeTableView.dataSource = self
pecodeTableView.register(UINib(nibName: S.CustomCell.customNewsCell, bundle: nil), forCellReuseIdentifier: S.CustomCell.customCellIdentifier)
// fetchAllNews()
viewModel.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
categoryMenu()
loadData()
}
private func loadNewsData(api: String){
let apiService = APIService(categoryCode: api)
apiService.getNewsData {(result) in
switch result{
case .success(let NewsOf):
CoreData.sharedInstance.saveDataOf(news: NewsOf.articles)
case .failure(let error):
print("Error processing json data: \(error)")
}
}
}
func reloadData(sender: NewsListViewModel) {
self.pecodeTableView.reloadData()
}
//MARK: - Networking
private func loadData(){
viewModel.retrieveDataFromCoreData()
}
//MARK: - UIView UImenu
func categoryMenu(){
var categoryAction: UIMenu{
let menuAction = Category.allCases.map { (item) -> UIAction in
let name = item.rawValue
return UIAction(title: name.capitalized, image: UIImage(systemName: item.systemImage)) { [weak self](_) in
self?.loadNewsData(api: name)
self?.loadData()
self?.reloadData(sender: self!.viewModel)
}
}
return UIMenu(title: "Change Category", children: menuAction)
}
let categoryButton = UIBarButtonItem(image: UIImage(systemName: "scroll"), menu: categoryAction)
navigationItem.leftBarButtonItem = categoryButton
}
@IBAction func goToFavouritesNews(_ sender: UIButton) {
performSegue(withIdentifier: S.Segues.goToFav, sender: self)
}
private func createSearchBar() {
navigationItem.searchController = searchVC
searchVC.searchBar.delegate = self
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.numberOfRowsInSection(section: section)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: S.CustomCell.customCellIdentifier, for: indexPath) as? CustomNewsCell
let object = viewModel.object(indexPath: indexPath)!
cell?.setCellWithValuesOf(object)
cell?.saveNewsBtn.tag = indexPath.row
cell?.saveNewsBtn.addTarget(self, action: #selector(didTapCellButton(sender:)), for: .touchUpInside)
return cell!
}
@objc func didTapCellButton(sender: FavouritesCell) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "SavedNews", in: context)
let newNewsSave = SavedNews(entity: entity!, insertInto: context)
newNewsSave.author = newsAuthor
newNewsSave.desc = newsDesc
newNewsSave.title = newsTitle
do {
try context.save()
savedNews.append(newNewsSave)
navigationController?.popViewController(animated: true)
} catch {
print("Error saving")
}
print("Done")
}
我还想向您展示my parsing functions and model
:*APIService.swift*
import Foundation
class APIService{
private var dataTask: URLSessionDataTask?
public let resourceURL: URL
private let API_KEY = "e2a69f7f9567451ba484c85614356c30"
private let host = "https://newsapi.org"
private let headlines = "/v2/top-headlines?"
init(categoryCode: String){
let resourceString = "\(host)\(headlines)country=us&category=\(categoryCode)&apiKey=\(API_KEY)"
print(resourceString)
guard let resourceURL = URL(string: resourceString) else {
fatalError()
}
self.resourceURL = resourceURL
}
//MARK: - Get News
func getNewsData(completion: @escaping (Result<Articles, Error>) -> Void){
dataTask = URLSession.shared.dataTask(with: resourceURL) { (data, response, error) in
if let error = error{
completion(.failure(error))
print("DataTask error: - \(error.localizedDescription)")
}
guard let response = response as? HTTPURLResponse else{
print("Empty Response")
return
}
print("Response status code: - \(response.statusCode)")
guard let data = data else {
print("Empty Data")
return
}
do{
let decoder = JSONDecoder()
let jsonData = try decoder.decode(Articles.self, from: data)
DispatchQueue.main.async {
completion(.success(jsonData))
}
}catch let error{
completion(.failure(error))
}
}
dataTask?.resume()
}
}
这是NewsModel.swift
:
import Foundation
struct Articles: Codable {
let articles: [News]
private enum CodingKeys: String, CodingKey{
case articles = "articles"
}
}
struct News: Codable {
let author: String?
let source: Source
let title: String
let description: String?
let url: URL?
let urlToImage: URL?
let publishedAt: String?
private enum CodingKeys: String, CodingKey{
case author = "author"
case title = "title"
case url = "url"
case urlToImage = "urlToImage"
case publishedAt = "publishedAt"
case description = "description"
case source = "source"
}
}
struct Source: Codable {
let name: String?
}
这是我的代码CustomNewsCell.swift
:
import UIKit
protocol CustomNewsDelegate: AnyObject {
func btnFavPress(cell: CustomNewsCell)
}
private var loadImage = LoadToImage()
private var formatDate = FormatDate()
class CustomNewsCell: UITableViewCell {
weak var delegate: CustomNewsDelegate?
@IBOutlet weak var saveNewsBtn: UIButton!
@IBOutlet weak var imageOutlet: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var descLabel: UILabel!
@IBOutlet weak var authorLabel: UILabel!
@IBOutlet weak var dateLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setCellWithValuesOf(_ news: SavedNews){
updateUI(title: news.title, url: news.url, urlToImage: news.urlToImage, publishedAt: news.publishedAt, author: news.author ?? "No author", description: news.desc, source: news.source)
}
private func updateUI(title: String?, url: URL?, urlToImage: URL?, publishedAt: String?, author: String, description: String?, source: String?){
//title
self.titleLabel.text = title
self.authorLabel.text = author
self.descLabel.text = description
//date
let dateString = formatDate.formatDate(from: publishedAt ?? "")
let date = formatDate.formatDateString(from: dateString)
self.dateLabel.text = date
//image
guard let urlToImageString = urlToImage else {return}
imageOutlet.image = nil
loadImage.getImageDataFrom(url: urlToImageString) { [weak self] data in
guard let data = data, let image = UIImage(data: data) else{
DispatchQueue.main.async {
self?.imageOutlet.image = UIImage(named: "noImage")
}
return
}
self?.imageOutlet.image = image
}
}
@IBAction func saveBtnPressed(_ sender: UIButton) {
delegate?.btnFavPress(cell: self)
}
}
我第一次尝试使用delegate method for this blue button
,但现在你可以看到我创建了一个selector method
. 也许它不正确,需要修复它。这是 中的代码second view controller
,应该show saved news from first view controller
:
import UIKit
import CoreData
var savedNews = [SavedNews]()
class FavouriteNewsViewController: UIViewController {
@IBOutlet weak var favTableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var result: [SavedNews] = []
var newsTitleNew: String?
var newsDescNew: String?
var newsAuthor: String?
override func viewDidLoad() {
super.viewDidLoad()
favTableView.delegate = self
favTableView.delegate = self
fetch()
// loadSavedNews()
favTableView.register(UINib(nibName: S.FavouriteCell.favouriteCell, bundle: nil), forCellReuseIdentifier: S.FavouriteCell.favouriteCellIdentifier)
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
// fetch()
favTableView.reloadData()
}
@IBAction func goToNewsFeed(_ sender: UIButton) {
performSegue(withIdentifier: S.Segues.goToNewsFeed, sender: self)
}
}
extension FavouriteNewsViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return savedNews.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 140
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = favTableView.dequeueReusableCell(withIdentifier: S.FavouriteCell.favouriteCellIdentifier, for: indexPath) as! FavouritesCell
let newRslt: SavedNews!
newRslt = savedNews[indexPath.row]
cell.favAuthor.text = newRslt.author
cell.favDesc.text = newRslt.desc
cell.favTitle.text = newRslt.title
return cell
}
func fetch() {
let request = NSFetchRequest<SavedNews>(entityName: "SavedNews")
do {
savedNews = try context.fetch(request)
} catch {
print(error)
}
}
}
和代码cell for this controller
:
import UIKit
import CoreData
class FavouritesCell: UITableViewCell {
@IBOutlet weak var favImage: UIImageView!
@IBOutlet weak var favTitle: UILabel!
@IBOutlet weak var favDesc: UILabel!
@IBOutlet weak var favAuthor: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
如果有人可以帮助解决这个问题,那将是惊人的。因为我真的不知道该怎么做。谢谢!
解决方案
推荐阅读
- mysql - MySQL:基于以后加入的表的加入条件
- python - 对于相同的模型架构,Keras 模型和 Caffe 模型的输出形状不同
- php - 无法在 Laravel-dompdf 中加载自定义字体文件`.otf`
- java - 无法在 Netbeans 的 Maven 项目中导入任何 javax-servlet
- ios - 在其他 UIViewController 中获取 AppDelegate 实例时出错
- c# - 无法通过 ajax 发布模型
- mysql - MySQL UPDATE 和 JOIN ON 同一列
- javascript - 嵌套在每个循环中以在数组中插入没有重复的值,并且循环从第一个开始
- reactjs - 来自 With Style 的访问类
- excel - Excel公式获取3个单元格中最常见的值?