Having trouble passing core data between view controllers

Hi guys, so I recently just started getting into core data and I’m at the point of my app where I need to start saving data onto the disk and I figured that core data is what I need. My app is a shoe profit analyzer that shoes whether a person profited or lost after selling a shoe. So in my app, I have 2 view controllers - (1) One main VC that has a UITableView populated with Shoe objects along with the name of the shoe, the price the shoe was bought, the price the shoe etc. The second VC allows a user to add a shoe to the cell via textfields.

Here is a picture of what I’m trying to describe:

(Above is just a mockup/mini version I created of my real app as the actual app is very intensive and can get very confusing)

My problem is passing the information that the user has filled out from the 2nd VC to the 1st VC and populating the table.

Here is the first VC and what I’ve created so far:

import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!

private var finalItems:[Shoe] = []
var finalName = ""
var finalBuy = ""
var finalSell = ""
var finalFee = ""

private var appDelegate = UIApplication.shared.delegate as! AppDelegate

private var managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext


//MARK: Functions
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return finalItems.count
}

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    
    let cell = tableView.dequeueReusableCell(withIdentifier: "ShoeCell", for: indexPath) as! CustomCells
    let shoe = finalItems[indexPath.row]
    
    cell.Name.text = "Name: \(shoe.name!)"
    //cell.buyPrice.text = "Age: $\(shoe.buyPrice!)"
    //cell.sellPrice.text = "Height: $\(shoe.sellPrice!)"
    //cell.transFee.text = "Gender: \(shoe.fee!)"
    
    return cell
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    let nameToSave = finalName
    let buyToSave = finalBuy
    let sellToSave = finalSell
    let feeToSave = finalFee
    
    let shoe = Shoe(entity: Shoe.entity(), insertInto: managedContext)
    shoe.name = nameToSave
    shoe.buyPrice = buyToSave
    shoe.sellPrice = sellToSave
    shoe.fee = feeToSave
    
    if(!finalName.isEmpty && !finalBuy.isEmpty && !finalFee.isEmpty && !finalSell.isEmpty){
    
    do {
        try managedContext.save()
        appDelegate.saveContext()
        finalItems.append(shoe)
    } catch let error as NSError {
        print("Error saving: \(error)")
        }

    }

    // Fetch a request to retrieve the data again
    do {
        finalItems = try managedContext.fetch(Shoe.fetchRequest())
    } catch let error as NSError {
        print("Error fetching request: \(error)")
    }
    
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    tableView.reloadData()
}

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.delegate = self
}

} 

and here is my code for allowing a user to add a Shoe object:

import UIKit
import CoreData

class AddViewController: UIViewController {

private var shoeItems:[Shoe] = []
var addName = ""
var addBuy = ""
var addSell = ""
var addFee = ""

@IBOutlet weak var nameText: UITextField!
@IBOutlet weak var buyText: UITextField!
@IBOutlet weak var sellText: UITextField!
@IBOutlet weak var feeText: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func addItem(_ sender: Any) {
    self.addName = nameText.text!
    self.addBuy = buyText.text!
    self.addSell = sellText.text!
    self.addFee = feeText.text!
    
    performSegue(withIdentifier: "addShoe", sender: self)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let vc = segue.destination as! ViewController
        vc.finalName = self.addName

}
} 

The problem I’m experiencing is that every time I rerun my application, a cell with empty strings is being added and I believe that’s because I set my finalName to equal "" but I’m unsure what solution I can do to remedy that.

Link to the cell after first run of the program: Imgur: The magic of the Internet

@johnbelarmino1 Thanks very much for your question!

Your problem is a very common problem, and the solution is to use the delegate pattern using protocols.

ViewController B should declare a protocol, along with a method, as well as a property of the protocol type. You would then have ViewController A implement the protocol that you declared in ViewController B, and assign itself as the delegate to the property you declared in ViewController B.

That’s a short summary of how you can do this.

I hope this helps!

All the best!

I sort of understand what you’re saying and I remember watching a tutorial about that, thank you!

This topic was automatically closed after 166 days. New replies are no longer allowed.