【问题标题】: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,而不是尝试让单例绕过容器。跨度>

标签: ios swift core-data


【解决方案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 控制器

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2017-10-14
    • 2021-10-10
    • 2015-02-26
    • 1970-01-01
    • 2016-08-19
    相关资源
    最近更新 更多