Partage
  • Partager sur Facebook
  • Partager sur Twitter

Cours : Gérer la navigation et les formulaires

Application Miawouf

    16 juin 2019 à 13:57:01

    Bonjour.

    Je me pose une question.

    Elle concerne le Développement Orienté Objet, et l'héritage.

    Dans ce cours, nous avons une application qui fonctionne pratiquement exactement de la même manière selon que l'on traite un chien ou un chat.

    Or donc...

    Pourquoi cette application ne traite pas de l'héritage ? C'est pourtant typique il me semble... A Mons que le fonctionnement du Storyboard ne le permette pas.

    Dupliquer du code n'est pas très productif.

    Suis-je dans le vrai, ou bien ?

    Bien à vous.

    • Partager sur Facebook
    • Partager sur Twitter
      16 juin 2019 à 18:38:10

      Salut,

      Je ne connais pas le cours, peux-tu illustrer avec du code et dire ce que tu trouves bizarre ?

      Quel est le code dupliqué que tu souhaites refactoriser ?

      • Partager sur Facebook
      • Partager sur Twitter
        16 juin 2019 à 19:30:48

        Hello.

        Voici une copie écran du storyboard :

        Comme on peut le voir, les 3 UIView Chat et Chien sont les mêmes, à part les images chat et chien de la première colonne de View, le contenu des Picker de la colonne 2 des View, et le label des boutons de la colonne 3 des View. A part ça, les comportements sont identiques.

        Je me demandais s'il n'était pas possible d'optimiser tout ça dans un premier temps, genre n'avoir que 3 View et non 6, paramètres en fonction du choix du TabView.

        Ensuite, mes contrôleurs ressemblent à ça:

        Là aussi, à part le préfixe (ou suffixe) Cat et Dog, dans le nom des contrôleurs et dans le code, tout est identique.

        Exemple pour CatFormViewController.Swift, et DogViewController.Swift : Les seules différences entre les deux, c'est que dans le premier, je préfixe ou suffixe Cat, et dans le second Dog. Pas très optimisé tout ça ;-)

        Code CatFormViewController

        // CatFormViewController
        
        import UIKit
        
        class CatFormViewController: UIViewController {
        
        // MARK: viewDidLoad
        
        override func viewDidLoad() {
        
        super.viewDidLoad()
        
        }
        
        // MARK: Properties
        
        var cat: Pet!
        
        // MARK: Outlets
        
        @IBOutlet weak var nameTextField: UITextField!
        
        @IBOutlet weak var phoneTextField: UITextField!
        
        @IBOutlet weak var genderSegmentedControl: UISegmentedControl!
        
        @IBOutlet weak var majoritySwitch: UISwitch!
        
        @IBOutlet weak var racePickerView: UIPickerView!
        
        }
        
        // MARK: - Keyboard
        
        extensionCatFormViewController: UITextFieldDelegate {
        
        @IBAction func dismissKeyBord(_ sender: UITapGestureRecognizer) {
        
        nameTextField.resignFirstResponder()
        
        phoneTextField.resignFirstResponder()
        
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        
        textField.resignFirstResponder()
        
        returntrue
        
        }
        
        }
        
        // MARK: - PickerView
        
        extensionCatFormViewController: UIPickerViewDataSource, UIPickerViewDelegate {
        
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
        
        return1
        
        }
        
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        
        returncatRaces.count
        
        }
        
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        
        return catRaces[row]
        
        }
        
        }
        
        // MARK: - Validate
        
        extensionCatFormViewController {
        
        @IBAction func validate(_ sender: Any) {
        
        createPetObject ()
        
        checkPetStatus()
        
        }
        
        private func createPetObject () {
        
        let name = nameTextField.text
        
        let phone = phoneTextField.text
        
        let hasMajority = majoritySwitch.isOn
        
        let gender: Pet.Gender = (genderSegmentedControl.selectedSegmentIndex == 0) ? .male : .female
        
        let raceIndex = racePickerView.selectedRow(inComponent: 0)
        
        let race = catRaces[raceIndex]
        
        cat = Pet(name: name, hasMajority: hasMajority, phone: phone, race: race, gender: gender)
        
        }
        
        private func checkPetStatus() {
        
        switchcat.status {
        
        case .accepted:
        
        performSegue(withIdentifier: "segueToSuccessCat", sender: nil)
        
        case .rejected(let error):
        
        presentAlert(with: error)
        
        }
        
        }
        
        private func presentAlert(with error: String) {
        
        let alert = UIAlertController(title: "Erreur", message: error, preferredStyle: .alert)
        
        let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        
        alert.addAction(action)
        
        present(alert, animated: true, completion: nil)
        
        }
        
        }
        
        // MARK: - Navigation
        
        extensionCatFormViewController {
        
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "segueToSuccessCat" {
        
        let successVC = segue.destination as! CatSuccessViewController
        
        successVC.cat = cat
        
        }
        
        }
        
        }
        

         Code DogFormViewController

        // DogFormViewController
        
        import UIKit
        
        class DogFormViewController: UIViewController {
        
        // MARK: viewDidLoad
        
        override func viewDidLoad() {
        
        super.viewDidLoad()
        
        }
        
        // MARK: Properties
        
        var dog: Pet!
        
        // MARK : Outlets
        
        @IBOutlet weak var nameTextField: UITextField!
        
        @IBOutlet weak var phoneTextField: UITextField!
        
        @IBOutlet weak var genderSegmentedControl: UISegmentedControl!
        
        @IBOutlet weak var majoritySwitch: UISwitch!
        
        @IBOutlet weak var racePickerView: UIPickerView!
        
        @IBOutletweakvar validate: UIButton!
        
        }
        
        // MARK: - Keyboard
        
        extensionDogFormViewController: UITextFieldDelegate {
        
        @IBAction func dismissKeyboard(_ sender: UITapGestureRecognizer) {
        
        nameTextField.resignFirstResponder()
        
        phoneTextField.resignFirstResponder()
        
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        
        textField.resignFirstResponder()
        
        returntrue
        
        }
        
        }
        
        // MARK: - PickerView
        
        extensionDogFormViewController: UIPickerViewDataSource, UIPickerViewDelegate {
        
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
        
        return1
        
        }
        
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        
        returndogRaces.count
        
        }
        
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        
        return dogRaces[row]
        
        }
        
        }
        
        // MARK: - Validate
        
        extensionDogFormViewController {
        
        @IBAction func validate(_ sender: Any) {
        
        createPetObject ()
        
        checkPetStatus()
        
        }
        
        private func createPetObject () {
        
        let name = nameTextField.text
        
        let phone = phoneTextField.text
        
        let hasMajority = majoritySwitch.isOn
        
        let gender: Pet.Gender = (genderSegmentedControl.selectedSegmentIndex == 0) ? .male : .female
        
        let raceIndex = racePickerView.selectedRow(inComponent: 0)
        
        let race = dogRaces[raceIndex]
        
        dog = Pet(name: name, hasMajority: hasMajority, phone: phone, race: race, gender: gender)
        
        }
        
        private func checkPetStatus() {
        
        switchdog.status {
        
        case .accepted:
        
        performSegue(withIdentifier: "segueToSuccessDog", sender: nil)
        
        case .rejected(let error):
        
        presentAlert(with: error)
        
        }
        
        }
        
        private func presentAlert(with error: String) {
        
        let alert = UIAlertController(title: "Erreur", message: error, preferredStyle: .alert)
        
        let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        
        alert.addAction(action)
        
        present(alert, animated: true, completion: nil)
        
        }
        
        }
        
        // MARK: - Navigation
        
        extensionDogFormViewController {
        
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "segueToSuccessDog" {
        
        let successVC = segue.destination as! DogSuccessViewController
        
        successVC.dog = dog
        
        }
        
        }
        
        }



        -
        Edité par GuillaumePigasse 16 juin 2019 à 22:50:45

        • Partager sur Facebook
        • Partager sur Twitter
          16 juin 2019 à 21:33:48

          Bonjour,

          Merci de colorer votre code à l'aide du bouton Code

          Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: java;">Votre code ici</pre>.

          • Partager sur Facebook
          • Partager sur Twitter
            16 juin 2019 à 22:52:17

            Bonsoir.

            Ok, j'ai fait la modification pour la mise en forme.

            A noter : Il n'y a pas Swift dans le type de code. Alors, j'ai pris par défaut Apple Script.

            Bien à vous.

            • Partager sur Facebook
            • Partager sur Twitter
              17 juin 2019 à 18:05:53

              C'est toujours peu lisible vu qu'il n'y pas d'indentation ;)

              Effectivement, ça n'a pas l'air très optimisé.

              Personnellement, je supprimerai une branche de truc "bleu". Et je ferais de l'injection de dépendance pour récupérer le bon module.

              Genre tu aurais un truc comme ça pour la page "Welcome" : 

              protocol WelcomePresenterProtocol {
                  func bindView(_ view: WelcomeViewProtocol)
                  func unbindView()
              }
              
              protocol WelcomeViewProtocol: class {
                  func setImage(_ image: String)
              }
              
              class CatWelcomePresenter: WelcomePresenterProtocol {
                  private weak var view: WelcomeViewProtocol? = nil
                  func bindView(_ view: WelcomeViewProtocol) {
                      self.view = view
                      self.view?.setImage("CatImage")
                  }
                  
                  func unbindView() {
                      view = nil
                  }
              }
              
              class WelcomeViewController {
                  private var presenter: WelcomePresenterProtocol! = nil
                  var image: String? = nil
                  
                  func viewWillAppear() {
                      // En vrai ici il faudrait récupérer via l'injection de dépendence
                      presenter = CatWelcomePresenter()
                      presenter.bindView(self)
                  }
              }
              
              extension WelcomeViewController: WelcomeViewProtocol {
                  func setImage(_ image: String) {
                      self.image = image
                  }
              }
              

              Avec pareil pour Dog. L'injection se ferait au tap sur la tabBar. On peut faire pareil avec tous.

              Pour l'injection de dépendance tu peux utiliser ça : https://github.com/Swinject/Swinject

              Il y a peut-être autre chose, j'ai pas trop regardé.

              • Partager sur Facebook
              • Partager sur Twitter
                19 juin 2019 à 20:26:36

                Bosoit Geda et merci pour ton retour.

                Je vais regarder tout ça de près.

                Bien à toi.

                G.

                • Partager sur Facebook
                • Partager sur Twitter

                Cours : Gérer la navigation et les formulaires

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown