如何将现有的单例表视图数据保存在核心数据中?
Posted
技术标签:
【中文标题】如何将现有的单例表视图数据保存在核心数据中?【英文标题】:How to save existing singleton table view data in core data? 【发布时间】:2019-06-08 19:27:05 【问题描述】:我的项目中有像 var fromSharedFood = SingletonCart.sharedFood.food
这样的单件购物车。我正在从 MainVC 获取所有食物数据到 DetailVC -> MyCartVC。我在 MainVC 中有表格视图。我想将 MainVC 表视图数据保存到 CoreData。
我的项目离线。现在,它与 web api 通信。我使用 Singleton 进行从 MainVC 到 DetailVC 到 MyCartVC 的数据转换。现在,如果用户登录系统,我需要用核心数据等保存他/她的购物车。 即用户将食物添加到购物车并注销他/她的购物车必须在重新登录时保存。
我尝试使用 UserDefaults self.myCartUserDefaults.set(myCartTableView.dataSource, forKey: "userCart")
,但这没有意义。
我为食物名称和价格创建了 CoreData 实体。
这是 MyCartVC
import UIKit
import CoreData
class MyCartViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
var fromDetailFoodNames = ""
var fromDetailFoodPrices = ""
var backgroundView: UIView?
@IBOutlet weak var myCartTableView: UITableView!
@IBOutlet weak var totalPriceLabel: UILabel!
private let persistentContainer = NSPersistentContainer(name: "MyCartData")
var food: Food?
var fromSharedFood = SingletonCart.sharedFood.food
//TODO: - Approve my cart
@IBAction func approveCart(_ sender: Any)
override func viewDidLoad()
super.viewDidLoad()
self.tabBarController?.tabBar.isHidden = false
myCartTableView.reloadData()
override func viewWillAppear(_ animated: Bool)
self.myCartTableView.reloadData()
if foodCoreData.count == 0
myCartTableView.setEmptyView(title: "Sepetinizde ürün bulunmamaktadır", message: "Seçtiğiniz yemekler burada listelenir.")
else
myCartTableView.restore()
self.tabBarController?.viewControllers![1].tabBarItem.badgeValue = "\(foodCoreData.count)"
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else
return
let managedContext =
appDelegate.persistentContainer.viewContext
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "MyCartData")
do
foodCoreData = try managedContext.fetch(fetchRequest)
print("COREDATA FETCH EDİLDİ")
catch let error as NSError
print("Could not fetch. \(error), \(error.userInfo)")
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if fromSharedFood.count != 0
tableView.restore()
return fromSharedFood.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let foodName = fromSharedFood[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "myCartCell", for: indexPath) as! MyCartTableViewCell
cell.myCartFoodNameLabel.text = foodName.ProductTitle
self.tabBarController?.viewControllers![1].tabBarItem.badgeValue = "\(fromSharedFood.count)"
cell.myCartFoodPriceLabel.text = foodName.PriceString
return cell
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
return true
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
fromSharedFood.remove(at: indexPath.row)
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .automatic)
if fromSharedFood.count == 0
myCartTableView.reloadData()
self.tabBarController?.viewControllers![1].tabBarItem.badgeValue = nil
else
self.tabBarController?.viewControllers![1].tabBarItem.badgeValue = "\(fromSharedFood.count)"
myCartTableView.restore()
tableView.endUpdates()
编辑:
我的数据来自带有addBasket()
按钮的DetailVC。首先,我尝试将 DetailVC 标签数据保存到核心数据。之后从 MyCartVC 获取但没有得到任何响应。
这里是 DetailVC:
import UIKit
import CoreData
class DetailViewController: UIViewController, TagListViewDelegate
@IBOutlet weak var foodTitle: UILabel!
@IBOutlet weak var foodSubTitle: UILabel!
@IBOutlet weak var foodPrice: UILabel!
@IBOutlet weak var foodQuantity: UILabel!
@IBOutlet weak var detailFoodImage: UIImageView!
@IBOutlet weak var tagListView: TagListView!
var window: UIWindow?
var detailFoodName = ""
var detailFoodPrice = ""
var detailPhotoData = String()
var searchFoods: String!
var priceFood: Double!
var foodCoreData: [NSManagedObject] = []
var food: Food?
override func viewDidLoad()
super.viewDidLoad()
foodQuantity.text = "1"
foodTitle.text = food?.ProductTitle ?? ""
foodPrice.text = food?.PriceString
foodSubTitle.text = food?.Description
tagListView.delegate = self
setupIngredientsTag()
self.tabBarController?.tabBar.isHidden = true
self.navigationController?.navigationItem.title = "Sipariş Detayı"
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "FoodOrder")
self.window?.rootViewController = viewController
func save(foodName: String, foodPrice: String)
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else
return
let managedContext =
appDelegate.persistentContainer.viewContext
let entity =
NSEntityDescription.entity(forEntityName: "MyCartData",
in: managedContext)!
let foods = NSManagedObject(entity: entity,
insertInto: managedContext)
foods.setValue(foodName, forKeyPath: "fromDetailFoodNames")
foods.setValue(foodPrice, forKeyPath: "fromDetailFoodPrices")
do
try managedContext.save()
foodCoreData.append(foods)
print("COREDATA KAYDEDİLDİ!")
catch let error as NSError
print("Could not save. \(error), \(error.userInfo)")
//TODO:- Add to basket
@IBAction func addBasket(_ sender: Any)
SingletonCart.sharedFood.food.append(food!)
self.performSegue(withIdentifier: "toMyCart", sender: nil)
self.navigationController?.navigationBar.isHidden = false
self.tabBarController?.tabBar.isHidden = false
self.isLoading(true)
guard let nameToSave = foodTitle.text else return
guard let priceToSave = foodPrice.text else return
self.save(foodName: nameToSave, foodPrice: priceToSave)
@IBAction func cancelButtonClicked(_ sender: UIBarButtonItem)
self.navigationController?.popViewController(animated: true)
@IBAction func favoriteButtonClicked(_ sender: UIBarButtonItem)
override func viewWillAppear(_ animated: Bool)
self.navigationController?.navigationBar.isHidden = false
override func viewWillDisappear(_ animated: Bool)
self.navigationController?.navigationBar.isHidden = true
SingletonCart
import Foundation
import UIKit
class SingletonCart
static let sharedFood = SingletonCart()
var food: [Food] = []
private init()
预期的输出是用户注销时保存他/她的购物车。
【问题讨论】:
你能在上面添加你的SingletonCart
类吗?目前尚不清楚这是如何工作的。
@jake singleton 添加了!
您的问题到底是什么? “怎么救……?”非常模糊,没有描述您的代码存在什么问题。
如果您要使用单例模式,您应该从那里保存您的 CoreData,而不是尝试让单例并绕过容器。跨度>
【参考方案1】:
从我所看到的情况来看,您有几个概念是错误的。 Core Data Programming Guide 将帮助您了解它的工作原理以及如何保存数据。
对于您的表格列表,您应该使用 NSFetchedResultsController 而不是自己管理集合。
然后,当从详细视图控制器添加新模型时,您应该创建一个新的背景上下文,创建实体,设置其值,然后保存它。
appDelegate.persistentContainer.performBackgroundTask (context) in
let entity =
NSEntityDescription.entity(forEntityName: "MyCartData",
in: managedContext)!
let foods = NSManagedObject(entity: entity,
insertInto: managedContext)
foods.setValue(foodName, forKeyPath: "fromDetailFoodNames")
foods.setValue(foodPrice, forKeyPath: "fromDetailFoodPrices")
_ = try? managedContext.save()
这会将这个对象保存到持久存储中,它们会刷新您的视图上下文,并且您的 NSFetchedResultsController 将自动更新您的 tableView 控制器
【讨论】:
以上是关于如何将现有的单例表视图数据保存在核心数据中?的主要内容,如果未能解决你的问题,请参考以下文章
Iphone 编程 - 将现有的 sql 表导入到 sqlite 或核心数据