如何将现有的单例表视图数据保存在核心数据中? [英] How to save existing singleton table view data in core data?

查看:53
本文介绍了如何将现有的单例表视图数据保存在核心数据中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目中有一个单例购物车,例如 var fromSharedFood = SingletonCart.sharedFood.food 。我正在从MainVC到DetailVC-> MyCartVC中获取所有食物数据。我在MainVC中有表视图。我想将MainVC表视图数据保存到CoreData。



我的项目处于脱机状态。现在,它与Web api通信。我使用Singleton从MainVC到DetailVC到MyCartVC进行数据转换。现在,如果用户登录系统,则需要用核心数据或其他内容保存他/她的购物车。
即用户在购物车中添加食物并注销,重新登录时必须保存他/她的购物车。 p>

我尝试使用UserDefaults self.myCartUserDefaults.set(myCartTableView.dataSource,forKey: userCart),但不是有道理。
我创建了食品名称和价格的CoreData实体。



这是MyCartVC

  import UIKit 
导入CoreData

类MyCartViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {

var fromDetailFoodNames =
var fromDetailFoodPrices =
var backgroundView:UIView?

@IBOutlet弱var myCartTableView:UITableView!
@IBOutlet弱var totalPriceLabel:UILabel!
private let持久容器= NSPersistentContainer(名称: MyCartData)

var食物:食物?

var fromSharedFood = SingletonCart.sharedFood.food

// TODO:-批准我的购物车
@IBAction func approveCart(_发件人:Any){
}

覆盖func viewDidLoad(){
super.viewDidLoad()
self.tabBarController?.tabBar.isHidden = false
myCartTableView.reloadData()
}



覆盖func viewWillAppear(_动画:Bool){

self.myCartTableView.reloadData()

if foodCoreData.count == 0 {

myCartTableView.setEmptyView(title: Sepetinizdeürünbulunmamaktadır,消息:Seçtiğinizyemekler burada listelenirir。)
}
其他{
myCartTableView.restore()
self.tabBarController?.viewControllers![1] .tabBarItem.badgeValue = \(foodCoreData.count)
卫队让appDelegate =
UIApplication.shared.delegate为? AppDelegate else {
return
}

让managedContext =
appDelegate.persistentContainer.viewContext

让fetchRequest =
NSFetchRequest< NSManagedObject>(实体名称: MyCartData)

do {
foodCoreData = trymanagedContext.fetch(fetchRequest)
print( COREDATA FETCHEDİLDİ)
} catch让错误作为NSError {
print(无法获取。\(error),\(error.userInfo))
}
}
}

func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {

,如果fromSharedFood.count!= 0 {
tableView.restore()
}

fromSharedFood.count
}

func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-> UITableViewCell {
let foodName = fromSharedFood [indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: myCartCell,for:indexPath)为! MyCartTableViewCell
cell.myCartFoodNameLabel.text = foodName.ProductTitle
self.tabBarController?.viewControllers![1] .tabBarItem.badgeValue = \(fromSharedFood.count)
cell.myCartFoodPriceLabel。文本= foodName.PriceString
返回单元格
}

func tableView(_ tableView:UITableView,canEditRowAt indexPath:IndexPath)->布尔{{
返回true
}

func tableView(_ tableView:UITableView,commit editStyle:UITableViewCell.EditingStyle,forRowAt indexPath:IndexPath){
如果editingStyle == .delete {
fromSharedFood.remove(at:indexPath.row)
tableView.beginUpdates()
tableView.deleteRows(at:[indexPath],其中:.automatic)

,如果fromSharedFood.count == 0 {
myCartTableView.reloadData()
self.tabBarController?.viewControllers![1] .tabBarItem.badgeValue = nil}
其他{
self.tabBarController?.viewControllers![1] .tabBarItem.badgeValue = \(fromSharedFood.count)
}
myCartTableView.restore()
}
tableView。 endUpdates()
}
}
}

编辑:



我的数据来自DetailVC,并带有 addBasket()按钮。首先,我尝试将DetailVC标签数据保存到核心数据中。之后,从MyCartVC获取了此信息,但未得到任何答复。



以下是DetailVC:

 导入UIKit 
导入CoreData

类DetailViewController:UIViewController,TagListViewDelegate {

@IBOutlet弱var foodTitle:UILabel !
@IBOutlet弱var foodSubTitle:UILabel!
@IBOutlet弱食食品价格:UILabel!
@IBOutlet弱var食物数量:UILabel!
@IBOutlet弱var detailFoodImage:UIImageView!

@IBOutlet弱变量tagListView:TagListView!

var window:UIWindow?

var detailFoodName =
var detailFoodPrice =
var detailPhotoData = String()

var searchFoods:字符串!
var priceFood:Double!

var foodCoreData:[NSManagedObject] = []
var food:食物?

覆盖功能funD viewDidLoad(){
super.viewDidLoad()

foodQuantity.text = 1

foodTitle.text =食物?.ProductTitle ??
foodPrice.text =食物?.PriceString
foodSubTitle.text =食物?。说明

tagListView.delegate =自我
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 :字符串,食品价格:字符串){

后卫让appDelegate =
UIApplication.shared.delegate为? AppDelegate else {
return
}


letmanagedContext =
appDelegate.persistentContainer.viewContext


let实体=
NSEntityDescription.entity(forEntityName: MyCartData,
在:managedContext中)!

let foods = NSManagedObject(实体:实体,
insertInto:managedContext)

foods.setValue(foodName,forKeyPath: fromDetailFoodNames)
食物.setValue(foodPrice,forKeyPath: fromDetailFoodPrices)

do {
trymanagedContext.save()
foodCoreData.append(foods)
print( COREDATAKAYDEDİLDİ !)
}捕获让错误作为NSError {
print(无法保存。\(error),\(error.userInfo))
}
}

//待办事项:-添加到购物篮
@IBAction func addBasket(_ sender:Any){

SingletonCart.sharedFood.food.append(food!)

self.performSegue(withIdentifier: toMyCart,发送者:nil)
self.navigationController?.navigationBar.isHidden = false
self.tabBarController?.tabBar.isHidden = false
self.isLoading(true)

guard let nameToSave = foodTitle.text else {return}
guard let priceTo保存= foodPrice.text else {return}

self.save(foodName:nameToSave,foodPrice:priceToSave)
}

@IBAction函数func cancelButtonClicked(_发送者: UIBarButtonItem){
self.navigationController?.popViewController(动画:true)

}
@IBAction func favoriteButtonClicked(_ sender:UIBarButtonItem){

}

覆盖func viewWillAppear(_动画:Bool){
self.navigationController?.navigationBar.isHidden = false

}

覆盖func viewWillDisappear(_动画:布尔){
self.navigationController?.navigationBar.isHidden = true
}

}

SingletonCart

 导入基金会
导入UIKit

类SingletonCart {
static let sharedFood = SingletonCart()
var food:[Food] = []

private init(){}
}

预期的输出是用户注销时保存他/她的时间s

解决方案

从我看来,您有两个错误的概念。 《核心数据编程指南》 将为您提供帮助要了解它如何工作以及如何保存数据。



对于表清单,您应该使用NSFetchedResultsController而不是自己管理集合。



然后,从局部视图控制器添加新模型时,您应该创建一个新的背景上下文,创建实体,设置其值然后保存。

  
appDelegate.persistentContainer.performBackgroundTask {(上下文)在
中,让实体=
NSEntityDescription.entity(forEntityName: MyCartData,
在:managedContext中)!

let foods = NSManagedObject(实体:实体,
insertInto:managedContext)

foods.setValue(foodName,forKeyPath: fromDetailFoodNames)
食物.setValue(foodPrice,forKeyPath: fromDetailFoodPrices)
_ =尝试吗? ManagedContext.save()
}

这会将这个对象保存到持久性存储中,它们刷新您的视图上下文,您的NSFetchedResultsController将自动更新您的tableView控制器


I have singleton shopping cart in my project like this var fromSharedFood = SingletonCart.sharedFood.food. I am getting all food data from MainVC to DetailVC -> MyCartVC. I have table view in MainVC. I want to save MainVC table view datas to CoreData.

My project was offline. Now, it communicates with web api. I used Singleton for data transition from MainVC to DetailVC to MyCartVC. Now, if user logged in the system I need to save him/her Cart with core data or etc. i.e. User add a food to cart and log out him/her Cart must be saved when re-login.

I tried with UserDefaults self.myCartUserDefaults.set(myCartTableView.dataSource, forKey: "userCart") but it is not make sense. I created CoreData entities for food name and price.

Here is 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()
    }
    }
    }

EDIT:

My data come from DetailVC with addBasket() button. First of all, I tried save DetailVC label datas to core data. After that fetched from MyCartVC but did not get any response.

Here is 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() {}
}

Expected output is when user logout save him/her shopping cart.

解决方案

You've got a couple of concepts wrong from what I see. Core Data Programming Guide will help you a lot to get how it works and how to save data.

For your table listings you should use an NSFetchedResultsController instead of managing a collection yourself.

Then when adding a new model from a detail View Controller you should create a new background context, create the entity, set its values and then save it.


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()
}

This will save this object to the persistent store, them refresh your view context and your NSFetchedResultsController will update your tableView controller automatically

这篇关于如何将现有的单例表视图数据保存在核心数据中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆