Как сохранить существующие данные представления таблицы синглтона в основных данных? - PullRequest
1 голос
/ 08 июня 2019

В моем проекте есть корзина синглтона, подобная этой var fromSharedFood = SingletonCart.sharedFood.food. Я получаю все данные о еде из MainVC в DetailVC -> MyCartVC. У меня есть вид таблицы в MainVC. Я хочу сохранить данные табличного представления MainVC в CoreData.

Мой проект был отключен. Теперь он общается с веб-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()
    }
    }
    }

EDIT:

Мои данные поступают из DetailVC с кнопкой addBasket(). Прежде всего я попытался сохранить данные меток 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 Ответ

1 голос
/ 17 июня 2019

Вы поняли пару понятий из того, что я вижу. Руководство по программированию основных данных поможет вам понять, как это работает и как сохранять данные.

Для ваших списков таблиц вы должны использовать NSFetchedResultsController вместо того, чтобы управлять коллекцией самостоятельно.

Затем при добавлении новой модели из подробного View Controller вы должны создать новый фоновый контекст, создать сущность, установить ее значения и затем сохранить ее.


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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...