Returning value from ViewController

So here is my issue.


I have VC1....VC4 in which the user enters a value into a field on each VC (1 thru 4) so I wanted to have a common piece of code that would take those values from each VC and process them to either save in core or to retrieve them for display.


VC1: A listing of weight lifting exercises (e.g., Chest, Legs, Back, etc) - this is where I want the common processing code to store and retrieve

VC2: Chest VC where the user will enter a weight lifted -> call VC (via segue and delegate)


So I can get the store and retrieve working but can not find a way to get the retrieved value back to VC2 to display. In VC1 the core memory is read fine ...just need to get that value BACK to VC2 and I AM STUCK.


Help?

-Bruce


VIEWCONTROLLER - has common functions called by other ViewControllers

import UIKit
import CoreData

class TimeSensitiveChestWorkout1: UIViewController, WeightProtocol {
    var Pressed: String!
    
    @IBOutlet weak var logo: UIImageView!
    @IBOutlet weak var Workout1: UIButton!
    @IBOutlet weak var Workout2: UIButton!
    @IBOutlet weak var Workout3: UIButton!

    @IBAction func didPressButton(sender:  AnyObject) {
        Pressed = "DumbbellPress"
    }
    
    @IBAction func inclineDumbbellPress(_ sender: Any) {
        Pressed = "inclineViewController"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        logo.layer.cornerRadius = 25
        logo.layer.masksToBounds = true
        logo.layer.borderColor = UIColor.white.cgColor
        logo.layer.borderWidth = 3
        
        Workout1.layer.cornerRadius = 20
        Workout1.layer.masksToBounds = true
        Workout1.layer.borderColor = UIColor.white.cgColor
        Workout1.layer.borderWidth = 2
        
        Workout2.layer.cornerRadius = 20
        Workout2.layer.masksToBounds = true
        Workout2.layer.borderColor = UIColor.white.cgColor
        Workout2.layer.borderWidth = 2
        
        Workout3.layer.cornerRadius = 20
        Workout3.layer.masksToBounds = true
        Workout3.layer.borderColor = UIColor.white.cgColor
        Workout3.layer.borderWidth = 2
    }
    
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (Pressed == "DumbbellPress") {
            let destination = segue.destination as! DumbbellChestPress
            destination.delegate = self
        }
        else if (Pressed == "inclineViewController") {
            let destination = segue.destination as! inclineViewController
            destination.delegate = self
        }
        else {
            print ("******** No button press")
        }
    }
    
    
    func updateDataGlobal(EntityVar: String, ExeriseNameVar: String, value:String){        
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        
        let fetchRequest:NSFetchRequest = NSFetchRequest.init(entityName: EntityVar)
        fetchRequest.predicate = NSPredicate(format: "name = %@", ExeriseNameVar)
        do
        {
            let test = try managedContext.fetch(fetchRequest)
            let objectUpdate = test[0] as! NSManagedObject
            objectUpdate.setValue(value, forKey: "weight")
            do{
                try managedContext.save()
            }
            catch
            {
                print("Error: ",error)
            }
        }
        catch
        {
            print(error)
        }
    }
    
    
    func retrieveDataGlobal(EntityVar: String, ExeriseNameVar: String, value:String) {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        
        let fetchRequest = NSFetchRequest(entityName: "Chest")
        fetchRequest.fetchLimit = 5
        fetchRequest.predicate = NSPredicate(format: "name = %@", ExeriseNameVar)
        
        let count = try! managedContext.count(for: fetchRequest)
        print (count)
        
        do {
            let result = try managedContext.fetch(fetchRequest)
            for data in result as! [NSManagedObject] {
            }
        } catch {
            print("Failed")
        }
    }


Viewcontroller that calls common code in previous controller


import UIKit
import CoreData

protocol WeightProtocol {
    func updateDataGlobal(EntityVar: String, ExeriseNameVar: String, value:String)
    func retrieveDataGlobal(EntityVar: String, ExeriseNameVar: String, value:String)
}

extension UIViewController {
    func HideKeyboard() {
        let Tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(DismissKeyboard))
        view.addGestureRecognizer(Tap)
    }
    @objc func DismissKeyboard() {
        view.endEditing(true)
    }
}

class DumbbellChestPress: UIViewController {
    var delegate: WeightProtocol!

    @IBOutlet weak var newMaxLiftText: UITextField!
    @IBOutlet weak var newMaxLiftLabel: UILabel!
    @IBOutlet weak var maxWeightLiftedLabel: UILabel!
    
    @IBAction func newWeightButon(_ sender: UIButton) {
        maxWeightLiftedLabel.text = newMaxLiftText.text
        delegate?.updateDataGlobal(EntityVar: "Chest", ExeriseNameVar: "Dumbell Chest Press", value: maxWeightLiftedLabel.text!)
        self.dismiss(animated: true, completion: nil)
    }
    
    @IBAction func delerteDataBtton(_ sender: UIButton) {
        deleteData()
    }
    
    @IBAction func loadDataButton(_ sender: UIButton) {
        createData()
    }
    
    @IBOutlet weak var Workout1: UIImageView!
    @IBOutlet weak var Workout2: UIImageView!
    
    @IBOutlet weak var Workout4: UIImageView!
    @IBOutlet weak var Workout3: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.HideKeyboard()
        
        delegate?.retrieveDataGlobal(EntityVar: "Chest", ExeriseNameVar: "Dumbell Chest Press", value: maxWeightLiftedLabel.text!)
        
        Workout1.layer.cornerRadius = 20
        Workout1.layer.masksToBounds = true
        Workout1.layer.borderColor = UIColor.white.cgColor
        Workout1.layer.borderWidth = 2
        
        Workout2.layer.cornerRadius = 20
        Workout2.layer.masksToBounds = true
        Workout2.layer.borderColor = UIColor.white.cgColor
        Workout2.layer.borderWidth = 2
        
        Workout3.layer.cornerRadius = 20
        Workout3.layer.masksToBounds = true
        Workout3.layer.borderColor = UIColor.white.cgColor
        Workout3.layer.borderWidth = 2
        
        Workout4.layer.cornerRadius = 20
        Workout4.layer.masksToBounds = true
        Workout4.layer.borderColor = UIColor.white.cgColor
        Workout4.layer.borderWidth = 2

    }


import UIKit
import CoreData

class TimeSensitiveChestWorkout1: UIViewController, WeightProtocol {
    var Pressed: String!
    
    @IBOutlet weak var logo: UIImageView!
    @IBOutlet weak var Workout1: UIButton!
    @IBOutlet weak var Workout2: UIButton!
    @IBOutlet weak var Workout3: UIButton!

    @IBAction func didPressButton(sender:  AnyObject) {
        Pressed = "DumbbellPress"
    }
    
    @IBAction func inclineDumbbellPress(_ sender: Any) {
        Pressed = "inclineViewController"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        logo.layer.cornerRadius = 25
        logo.layer.masksToBounds = true
        logo.layer.borderColor = UIColor.white.cgColor
        logo.layer.borderWidth = 3
        
        Workout1.layer.cornerRadius = 20
        Workout1.layer.masksToBounds = true
        Workout1.layer.borderColor = UIColor.white.cgColor
        Workout1.layer.borderWidth = 2
        
        Workout2.layer.cornerRadius = 20
        Workout2.layer.masksToBounds = true
        Workout2.layer.borderColor = UIColor.white.cgColor
        Workout2.layer.borderWidth = 2
        
        Workout3.layer.cornerRadius = 20
        Workout3.layer.masksToBounds = true
        Workout3.layer.borderColor = UIColor.white.cgColor
        Workout3.layer.borderWidth = 2
    }
    
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (Pressed == "DumbbellPress") {
            let destination = segue.destination as! DumbbellChestPress
            destination.delegate = self
        }
        else if (Pressed == "inclineViewController") {
            let destination = segue.destination as! inclineViewController
            destination.delegate = self
        }
        else {
            print ("******** No button press")
        }
    }
    
    
    func updateDataGlobal(EntityVar: String, ExeriseNameVar: String, value:String){        
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        
        let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: EntityVar)
        fetchRequest.predicate = NSPredicate(format: "name = %@", ExeriseNameVar)
        do
        {
            let test = try managedContext.fetch(fetchRequest)
            let objectUpdate = test[0] as! NSManagedObject
            objectUpdate.setValue(value, forKey: "weight")
            do{
                try managedContext.save()
            }
            catch
            {
                print("Error: ",error)
            }
        }
        catch
        {
            print(error)
        }
    }
    
    
    func retrieveDataGlobal(EntityVar: String, ExeriseNameVar: String, value:String) {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Chest")
        fetchRequest.fetchLimit = 5
        fetchRequest.predicate = NSPredicate(format: "name = %@", ExeriseNameVar)
        
        let count = try! managedContext.count(for: fetchRequest)
        print (count)
        
        do {
            let result = try managedContext.fetch(fetchRequest)
            for data in result as! [NSManagedObject] {
            }
        } catch {
            print("Failed")
        }
    }

Replies

Seems you have posted twice some same part of code (TimeSensitiveChestWorkout1).

You say:

I wanted to have a common piece of code that would take those values from each VC and process them to either save in core or to retrieve them for display.


Can you explain the set up:


in VC1 you have all the paramaters ? Is it TimeSensitiveChestWorkout1 ?

in VC2…VC4, each has some of the parameters ? Are they DumbbellChestPress…


Remark: you use too much implicit unwrap:

For instance

var delegate: WeightProtocol!


It should be

var delegate: WeightProtocol?


otherwise, you have a risk of crash.

I think this is from your previous thread. Why can't you move updateDataGlobal and retrieveDataGlobal into separate functions that are not methods of the class TimeSensitiveChestWorkout1? You get all the required references as part of the processing in each function from the AppDelegate, so they don't look like they depend on the state of TimeSensitiveChestWorkout1. Then, you can call them from any view controller, without worrying about dependencies from each.

The updateDataObject and retrieveDataObject should be considered part of your model, not your controller. They are the interfaces to your CoreData structure (your model) which is independent of the controllers. The separation between Models, Views, and Controllers is the fundamental design paradigm behind UIKit and Appkit, and keeping those lines of separation will make your programming tasks much easier .