3 Replies
      Latest reply on Jan 8, 2019 12:32 PM by jonprescott
      tekgeek1 Level 1 Level 1 (0 points)

        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")
                }
            }
        
        • Re: Returning value from ViewController
          Claude31 Level 8 Level 8 (6,335 points)

          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.

          • Re: Returning value from ViewController
            jonprescott Level 2 Level 2 (80 points)

            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.

            • Re: Returning value from ViewController
              jonprescott Level 2 Level 2 (80 points)

              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 .