如何将现有的单例表视图数据保存在核心数据中?

时间:2019-06-08 19:27:05

标签: ios swift core-data

我的项目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() {}
}

预期的输出是当用户注销保存他/她的购物车时

1 个答案:

答案 0 :(得分: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控制器