{"id":1998,"date":"2014-10-12T16:37:25","date_gmt":"2014-10-12T20:37:25","guid":{"rendered":"http:\/\/tim.cstj.qc.ca\/cours\/xcode\/wp\/?page_id=1998"},"modified":"2014-10-12T16:37:25","modified_gmt":"2014-10-12T20:37:25","slug":"projet-aquarium-poo-et-protocols","status":"publish","type":"page","link":"https:\/\/ve2cuy.com\/xcode\/projet-aquarium-poo-et-protocols\/","title":{"rendered":"Projet: Aquarium &#8211; POO et protocoles"},"content":{"rendered":"<h1>Contenu<\/h1>\n<h1><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-2091\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium-b2-330x600.png\" alt=\"aquarium-b2\" width=\"218\" height=\"397\" \/><\/h1>\n<p>&nbsp;<\/p>\n<ul>\n<li>Construction d&rsquo;une classe Swift<\/li>\n<li>Propri\u00e9t\u00e9s<\/li>\n<li>M\u00e9thodes<\/li>\n<li>Constructeur: init(Param1, Param2, Param3)<\/li>\n<li>Constructeur de convenance: init(param1)<\/li>\n<li>Destructeur: deinit<\/li>\n<li>Construction d&rsquo;une classe avec interface visuelle (super classe:UIImageView)<\/li>\n<li>Animer une s\u00e9rie d&rsquo;images<\/li>\n<li>Programmation d&rsquo;un NSTimer<\/li>\n<li>D\u00e9finition d&rsquo;un protocole personnalis\u00e9<\/li>\n<li>Gestion du protocole<\/li>\n<li>Gestion de l&rsquo;\u00e9cran tactile: touchesBegan<\/li>\n<\/ul>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<h1>\u00a0Note de mise \u00e0 jour de Xcode 6.0 vers 6.4<\/h1>\n<p>Remplacer<\/p>\n<ul>\n<li><strong><span style=\"color: #333399;\">let touch : UITouch = touches.anyObject as! UITouch<\/span><\/strong><\/li>\n<\/ul>\n<p>par<\/p>\n<ul>\n<li><strong><span style=\"color: #333399;\">let touch : UITouch = touches.first as! UITouch<\/span><\/strong><\/li>\n<\/ul>\n<hr \/>\n<p>&nbsp;<\/p>\n<h1>Description<\/h1>\n<h3>Objectif du laboratoire<\/h3>\n<p>Introduire aux\u00a0concepts de la programmation orient\u00e9e objet (POO) sous le langage Swift ainsi qu&rsquo;\u00e0 la notion de programmation de protocoles.<\/p>\n<h3>Contexte de r\u00e9alisation<\/h3>\n<p>Grace \u00e0 Xcode, au langage Swift, \u00e0 la POO sous Swift, \u00e0 une suite d&rsquo;images d&rsquo;animation,\u00a0\u00e0 un protocole personnalis\u00e9, au concept de d\u00e9l\u00e9gu\u00e9, \u00e0 un temporisateur, \u00e0 la gestuelle d&rsquo;\u00e9cran, aux propri\u00e9t\u00e9s du cadre d&rsquo;une vue, \u00e0 la hi\u00e9rarchie &lsquo;vue\/sous-vues&rsquo;, nous b\u00e2tirons\u00a0une application qui propose un micro syst\u00e8me de type &lsquo;aquarium\/poissons \u00e0 nourrir\/plantes produisant de l&rsquo;oxyg\u00e8ne&rsquo;.<\/p>\n<h3>Vid\u00e9o de l&rsquo;application compl\u00e9t\u00e9e<\/h3>\n<p><span style=\"color: #000000;\">[embedyt]http:\/\/www.youtube.com\/watch?v=JhlEASo1AqM[\/embedyt]<\/span><\/p>\n<hr \/>\n<h1><\/h1>\n<h1>Le storyBoard de la version finale<\/h1>\n<p>&nbsp;<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2092\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium-b1.png\" alt=\"aquarium-b1\" width=\"779\" height=\"613\" \/><br \/>\n&nbsp;<br \/>\n<a href=\"https:\/\/github.com\/puyansude\/Projet-Aquarium-la-POO-version-de-depart\/archive\/master.zip\">Projet-Aquarium-depart<\/a><\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<h1><\/h1>\n<h1>\u00c9tape 1 &#8211; Construction d&rsquo;une classe personnalis\u00e9e en Swift<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.1<\/strong> <\/span>&#8211; Ouvrons\u00a0et ex\u00e9cutons le projet de d\u00e9part.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2011\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.04-325x600.png\" alt=\"aquarium.04\" width=\"325\" height=\"600\" \/><br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.2<\/strong><\/span> &#8211; Examinons la console de Xcode<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2012\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.05.png\" alt=\"aquarium.05\" width=\"444\" height=\"163\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.3<\/strong> <\/span>&#8211; Analysons le code de la classe de la sc\u00e8ne principale.<\/p>\n<pre class=\"lang:swift decode:true\">\/\/\n\/\/  ViewController.swift\n\/\/  Classe - Aquarium\n\/\/\n\/\/  Created by Alain on 2014-10-11.\n\/\/  Copyright (c) 2014 Production sur support. All rights reserved.\n\/\/\n\/\/  ============================================================================================\n\/\/  \u00c0 l'usage exclusif des \u00e9tudiants et \u00e9tudiantes de\n\/\/  Techniques d'Int\u00e9gration Multim\u00e9dia\n\/\/  du c\u00e9gep de Saint-J\u00e9r\u00f4me.\n\/\/  --------------------------------------------------------------------------------------------\n\/\/  Il est interdit de reproduire, en tout ou en partie, \u00e0 des fins commerciales,\n\/\/  le code source, les sc\u00e8nes, les \u00e9l\u00e9ments graphiques, les classes et\n\/\/  tout autre contenu du pr\u00e9sent projet sans l\u2019autorisation \u00e9crite de l'auteur.\n\/\/\n\/\/  Pour obtenir l\u2019autorisation de reproduire ou d\u2019utiliser, en tout ou en partie,\n\/\/  le pr\u00e9sent projet, veuillez communiquer avec:\n\/\/\n\/\/  Alain Boudreault, aboudrea@cstj.qc.ca\n\/\/\n\/\/  ============================================================================================\nimport UIKit\nclass ViewController: UIViewController{\n    \/\/ ***********************************************************************\n    \/\/ D\u00e9finition des IBOutlet\n    \/\/ ***********************************************************************\n    @IBOutlet weak var labelNBPoissons: UILabel!\n    @IBOutlet weak var niveauNourriture: UIProgressView!\n    @IBOutlet weak var finPartie: UIView!\n    \/\/ ***********************************************************************\n    \/\/ D\u00e9finition des propri\u00e9t\u00e9s de la classe ViewController\n    \/\/ ***********************************************************************\n    let maximumNourritureDisponible = 100\n    let unePortionDeNourriture      = 20\n    var nourritureDisponible        = 0\n    let nbPoissonsDepart            = 5\n    var nbPoissons                  = 0\n    var modelesPoisson              = [[\"nom\":\"p11\", \"nbImages\":\"8\"],[\"nom\":\"p12\", \"nbImages\":\"5\"], [\"nom\":\"p13\", \"nbImages\":\"8\"]]\n    \/\/ ***********************************************************************\n    \/\/ D\u00e9finition des IBAction\n    \/\/ ***********************************************************************\n    @IBAction func recommencer(sender: AnyObject) {\n        println(\"recommencer\")\n        commencerLaPartie()\n    } \/\/ recommencer\n    @IBAction func ajouterNourriture(sender: AnyObject) {\n        println(\"ajouterNourriture\")\n        \/\/ Ajouter \u00e0 la nourriture disponible un poucentage de la quant actuelle.\n        nourritureDisponible += Int(arc4random_uniform(UInt32(nourritureDisponible)))\n        \/\/ S'assurer que la quant de nourriture ne d\u00e9passe pas le maximum\n        nourritureDisponible = nourritureDisponible &gt;  maximumNourritureDisponible ? maximumNourritureDisponible : nourritureDisponible\n        actualiserProgressViewQuantNourriture()\n    }  \/\/ ajouterNourriture\n    \/\/ ***********************************************************************\n    \/\/ M\u00e9thodes de la classe ViewController\n    \/\/ ***********************************************************************\n    override func viewDidLoad() {\n        println(\"viewDidLoad\")\n        super.viewDidLoad()\n        \/\/ Ajouter des bulles\n        \/\/ TODO\n        \/\/ Pr\u00e9parer l'aquarium\n        commencerLaPartie()\n    } \/\/ viewDidLoad\n    \/**\n      Pr\u00e9parer la sc\u00e8ne et placer les poissons.\n    *\/\n    func commencerLaPartie(){\n        println(\"commencerLaPartie\")\n        \/\/ Masquer la View de fin de la partie\n        finPartie.hidden = true\n        nourritureDisponible = maximumNourritureDisponible\n        actualiserProgressViewQuantNourriture()\n        nbPoissons = nbPoissonsDepart\n        actualiserLabelNBPoissons()\n        \/\/ Ajouter des poissons\n        ajouterLesPoissons(nbPoissons)\n    } \/\/ commencerLaPartie\n    \/**\n      R\u00e9actualiser l'indicateur du nombres de poissons.\n    *\/\n    func actualiserLabelNBPoissons(){\n        println(\"actualiserLabelNBPoissons\")\n        labelNBPoissons.text = \"\\(nbPoissons)\"\n    } \/\/ actualiserLabelNBPoissons\n    \/**\n        R\u00e9actualiser l'indicateur quantit\u00e9 de nourriture.\n    *\/\n    func actualiserProgressViewQuantNourriture(){\n        println(\"actualiserProgressViewQuantNourriture\")\n        niveauNourriture.progress = Float(nourritureDisponible) \/ 100.0\n    } \/\/ actualiserQuantNourriture\n    \/**\n    Cr\u00e9er des poissons et les ajouter \u00e0 la sc\u00e8ne principale.\n    *\/\n    func ajouterLesPoissons(quantite:Int){\n        println(\"ajouterLesPoissons\")\n        \/\/ TODO\n    } \/\/ ajouterLesPoissons\n    override func didReceiveMemoryWarning() {\n        println(\"didReceiveMemoryWarning\")\n        super.didReceiveMemoryWarning()\n        \/\/ Dispose of any resources that can be recreated.\n    } \/\/ didReceiveMemoryWarning\n}  \/\/ Fin de la classe ViewController<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.4<\/strong>\u00a0<\/span>&#8211; Ajoutons un nouveau fichier Swift au projet.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2015\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.06-800x366.png\" alt=\"aquarium.06\" width=\"800\" height=\"366\" \/> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2016\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.07-601x600.png\" alt=\"aquarium.07\" width=\"601\" height=\"600\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.5<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivant au fichier Poisson.Swift:<\/p>\n<pre class=\"lang:swift decode:true\">\/**\n  Classe permettant de cr\u00e9er un gentil petit poisson rouge...\n*\/\nclass Poisson {\n    \/\/ Propri\u00e9t\u00e9s\n    \/\/ Constructeur: init()\n    \/\/ Destructeur: deinit\n    \/\/ M\u00e9thodes\n} \/\/ class Poisson<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.5<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivant \u00e0 la m\u00e9thode ViewDidLoad:<br \/>\nRemarquez, notre commentaire appara\u00eet dans le module de compl\u00e9tion du code:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2133\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium2.1.png\" alt=\"aquarium2.1\" width=\"538\" height=\"190\" \/><br \/>\n&nbsp;<\/p>\n<pre class=\"lang:swift decode:true\">        let unPoisson = Poisson()<\/pre>\n<p>&nbsp;<br \/>\n&nbsp;<br \/>\nVoil\u00e0, nous venons de cr\u00e9er notre premier poisson! Par contre, c&rsquo;est un poisson\u00a0pas tr\u00e8s utile car il n&rsquo;a ni m\u00e9thode ni propri\u00e9t\u00e9.<\/p>\n<h1><\/h1>\n<hr \/>\n<h1>La m\u00e9thode init() &#8211; constructeur<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.6<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivant \u00e0 la classe Poisson<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Constructeur\n    init() {\n       println(\"Je suis le constructeur de Poisson.\")\n    } \/\/ init<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.7<\/strong>\u00a0<\/span>&#8211; Ex\u00e9cutons l&rsquo;application et analysons la console d&rsquo;Xcode.<br \/>\n&nbsp;<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2017\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.08.png\" alt=\"aquarium.08\" width=\"451\" height=\"179\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.8<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivant \u00e0 la classe Poisson<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Propri\u00e9t\u00e9s\n    \/\/\/ Une chaine d\u00e9crivant le poisson.\n    var nomPoisson:String\n    \/\/\/ Le nom du fichier qui contient l'image.\n    var nomImage:String\n    var force:Int\n    let seuilDangerDeMort = 10\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.9<\/strong>\u00a0<\/span>&#8211; Observons l&rsquo;erreur suivante:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2019\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.09.png\" alt=\"aquarium.09\" width=\"672\" height=\"302\" \/><br \/>\n<span style=\"color: #ff0000;\"><strong>Explication<\/strong><\/span>: \u00a0En Swift, \u00e0 moins d&rsquo;\u00eatre de type optionnel (uneVar?), les propri\u00e9t\u00e9s doivent-\u00eatre initialis\u00e9es avec du contenu, comme dans le cas de la propri\u00e9t\u00e9 &lsquo;seuilDangerDeMort&rsquo;. \u00a0Cette\u00a0initialisation est faite dans le constructeur, r\u00e8gle g\u00e9n\u00e9rale, \u00e0 partir des param\u00e8tres re\u00e7us.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.10<\/strong>\u00a0<\/span>&#8211; Modifions la classe Poisson.<\/p>\n<pre class=\"lang:swift decode:true\">import Foundation\nclass Poisson {\n    \/\/ Propri\u00e9t\u00e9s\n    var nomPoisson:String\n    var nomImage:String\n    var force:Int\n    let seuilDangerDeMort = 10\n    \/\/ Constructeur\n    \/**\n      Construire un poisson \u00e0 partir d'un nom et d'une force\n    *\/\n    init(nomPoisson:String, force:Int) {\n       println(\"Je suis le constructeur de Poisson.\")\n       self.nomPoisson  = nomPoisson\n       self.force       = force\n       self.nomImage    = \"n\/a\"\n    } \/\/ init()\n    \/\/ M\u00e9thodes\n    \/**\n      Je retourne une jolie description du poisson\n    *\/\n    func quiSuisJe() -&gt;String {\n        return \"\\n------------------\\nJe suis le poisson \\(nomPoisson) et j'ai une force de \\(force)\\n\"\n    } \/\/ quiSuisJe()\n} \/\/ class Poisson<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.11<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivante \u00e0 la m\u00e9thode ViewDidLoad:<\/p>\n<pre class=\"lang:swift decode:true\">        let unPoisson = Poisson(nomPoisson: \"Bob\", force: 99)\n        println( unPoisson.quiSuisJe() )\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.11b &#8211;<\/strong> <\/span>Construisons une nouvelle classe \u00e0 partir de la classe Poisson<\/p>\n<pre class=\"lang:swift decode:true\">class PoissonVolant: Poisson {\n    var hauteurDuVol:Int\n    init(nomPoisson: String, force: Int, hauteurDuVol:Int) {\n        \/\/ Note: Il faut initialiser les propri\u00e9t\u00e9s avant l'appel de la super classe.\n        self.hauteurDuVol = hauteurDuVol\n        super.init(nomPoisson: nomPoisson, force: force)\n    } \/\/ init\n} \/\/ PoissonVolant<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.11d<\/strong>\u00a0<\/span>&#8211; Testons avec le code suivant:<\/p>\n<pre class=\"lang:swift decode:true\">       let unPoissonVolant = PoissonVolant(nomPoisson: \"Exocoetidae\", force: 99, hauteurDuVol: 66)\n        println(unPoissonVolant.quiSuisJe())\n\/\/\/ R\u00e9sultat:\n------------------\nJe suis le poisson Exocoetidae et j'ai une force de 99<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.11e<\/strong>\u00a0<\/span>&#8211;\u00a0Surchargeons la m\u00e9thode description()<\/p>\n<pre class=\"lang:swift decode:true\">    \/**\n    Je retourne une jolie description du poisson volant\n    *\/\n    override func quiSuisJe() -&gt;String {\n        return \"\\n------------------\\nJe suis une poisson volant de type:\\(nomPoisson) et je saute \u00e0 \\(hauteurDuVol) pied(s)\\n\"\n    } \/\/ quiSuisJe()\n\/\/\/ R\u00e9sultat:\n------------------\nJe suis une poisson volant de type:Exocoetidae et je saute \u00e0 66 pied(s)<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h1>R\u00e9f\u00e9rence versus valeur<\/h1>\n<p>Le language Swift propose deux fa\u00e7ons de regrouper des propri\u00e9t\u00e9s et des m\u00e9thodes: soit par le mot cl\u00e9 &lsquo;class&rsquo; ou le mot cl\u00e9 &lsquo;struct&rsquo;.<br \/>\nPar exemple, il est possible de cr\u00e9er un\u00a0ensemble &lsquo;propri\u00e9t\u00e9s\/m\u00e9thodes&rsquo; Poisson de la fa\u00e7on suivante:<\/p>\n<pre class=\"lang:swift decode:true\">\/**\n  Structure Poisson.  Les instances de ce type seront copi\u00e9es lorsque pass\u00e9es en param\u00e8tre \u00e0 une fonction ou une m\u00e9thode.\n*\/\nstruct Poisson {\n    \/\/ Propri\u00e9t\u00e9s\n    \/\/ Constructeur: init()\n    \/\/ Destructeur: deinit\n    \/\/ M\u00e9thodes\n} \/\/ struct Poisson<\/pre>\n<p>La diff\u00e9rence \u00e9tant que les instances de classe sont pass\u00e9es en r\u00e9f\u00e9rence &#8211; c-a-d, le param\u00e8tre re\u00e7u est l&rsquo;instance originale de l&rsquo;objet, \u00a0alors que les structures sont pass\u00e9es par copie de l&rsquo;objet.<br \/>\n&nbsp;<\/p>\n<hr \/>\n<h1>Visibilit\u00e9\u00a0des \u00e9l\u00e9ments d&rsquo;une classe &#8211; (Class Access Control)<\/h1>\n<h3><span style=\"color: #808000;\"><strong>public<\/strong><\/span><\/h3>\n<p>Visible partout.<\/p>\n<h3><span style=\"color: #808000;\">internal (par d\u00e9faut)<\/span><\/h3>\n<p>Visible dans tous les fichiers du projet (app) ou de la librairie.<\/p>\n<h3><span style=\"color: #808000;\">private<\/span><\/h3>\n<p>Visible seulement dans le fichier courant.<br \/>\nExemple,<\/p>\n<pre class=\"lang:swift decode:true\">class Poisson {\n    public var nomPoisson:String\n    var nomImage:String  \/\/ internal par d\u00e9faut\n    private var force:Int\n    private let seuilDangerDeMort = 10\n    \/\/ internal par d\u00e9faut\n    init(nomPoisson:String, force:Int) {\n       println(\"Je suis le constructeur de Poisson.\")\n       self.nomPoisson  = nomPoisson\n       self.force       = force\n       self.nomImage    = \"n\/a\"\n    } \/\/ init()\n    private func lireForce()-&gt; Int{\n       return self.force\n    }\n    public func quiSuisJe() -&gt;String {\n        return \"Poisson de force: \\(lireForce())\"\n    } \/\/ quiSuisJe()\n} \/\/ class Poisson<\/pre>\n<h1><\/h1>\n<hr \/>\n<h1 id=\"art_title\" class=\"ftSize20 ftBold marB15\" style=\"color: #303030;\">Accesseurs et mutateurs &#8211;\u00a0get\/set (computed properties)<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Attention<\/strong><\/span>: Ne pas modifier votre classe &lsquo;poisson&rsquo;<\/p>\n<pre class=\"lang:swift decode:true\">\/\/\n\/\/  Poisson.swift\n\/\/  Projet - Aquarium\n\/\/\n\/\/  Created by Alain on 15-10-16.\n\/\/  Copyright (c) 2015 Production sur support. All rights reserved.\n\/\/\nimport Foundation\n\/**\nClasse permettant de cr\u00e9er un gentil petit poisson rouge...\n*\/\nclass Poisson {\n    internal var    _nomPoisson:String\n    var             _nomImage:String            \/\/ internal par d\u00e9faut\n    private var     _force:Int\n    private let     _seuilDangerDeMort = 10\n    \/\/ computed properties\n    var force: Int {\n        get {\n            println(\"Dans le getter de 'force' du poisson \\(_nomPoisson) avec une force de \\(_force)\")\n            if _force == 0 { return 3141592 }\n            return _force\n        }\n        set (valeur){\n            println(\"Dans le setter de 'force' du poisson \\(_nomPoisson) avec une force de \\(valeur)\")\n            if valeur &lt; 0 { _force = 0 }\n        }\n    }\n    \/\/ internal par d\u00e9faut\n    init(nomPoisson:String, force:Int) {\n        println(\"Je suis le constructeur de Poisson.\")\n        _nomPoisson  = nomPoisson\n        _force       = force\n        _nomImage    = \"n\/a\"\n    } \/\/ init()\n    private func lireForce()-&gt; Int{\n        return _force\n    }\n    internal func quiSuisJe() -&gt;String {\n        return \"Poisson de force: \\(lireForce())\"\n    } \/\/ quiSuisJe()\n} \/\/ class Poisson<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: Une propri\u00e9t\u00e9 de type &lsquo;computed&rsquo; sans &lsquo;setter&rsquo; sera alors de type &lsquo;lecture seulement&rsquo;.<br \/>\n&nbsp;<\/p>\n<hr \/>\n<h1>Observateurs d&rsquo;acc\u00e8s \u00e0 une propri\u00e9t\u00e9<\/h1>\n<p>&nbsp;<\/p>\n<pre class=\"lang:swift decode:true\">class StepCounter {\n    var totalSteps: Int = 0 {\n        willSet(newTotalSteps) {\n            println(\"About to set totalSteps to \\(newTotalSteps)\")\n        }\n        didSet {\n            if totalSteps &gt; oldValue  {\n                println(\"Added \\(totalSteps - oldValue) steps\")\n            }\n        }\n    }\n}\nlet stepCounter = StepCounter()\nstepCounter.totalSteps = 200\n\/\/ About to set totalSteps to 200\n\/\/ Added 200 steps\nstepCounter.totalSteps = 360\n\/\/ About to set totalSteps to 360\n\/\/ Added 160 steps\nstepCounter.totalSteps = 896\n\/\/ About to set totalSteps to 896\n\/\/ Added 536 steps\n\/\/ Note: R\u00e9f\u00e9rence: https:\/\/developer.apple.com\/library\/ios\/documentation\/swift\/conceptual\/swift_programming_language\/Properties.html<\/pre>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n<hr \/>\n<h1>Propri\u00e9t\u00e9 calcul\u00e9e (voir accesseur)<\/h1>\n<p>&nbsp;<\/p>\n<pre class=\"lang:swift decode:true\">\/\/ \u00c9tant donn\u00e9:\n\/\/ self.nom = \"Lafrance\"\n\/\/ self.titre = \"Monsieur\"\nvar properNom: String {\n  return self.titre + \" \" + self.nom\n}\nprintln(\"Je suis \\(properNom).)\n\/\/ Donne:\nJe suis Monsieur Lafrance.<\/pre>\n<p><strong><span style=\"color: #ff0000;\">Note<\/span><\/strong>: \u00a0&lsquo;properNom&rsquo; n&rsquo;est pas consid\u00e9r\u00e9e comme \u00e9tant une fonction mais une propri\u00e9t\u00e9 calcul\u00e9e (computed propertie).<br \/>\n&nbsp;<\/p>\n<hr \/>\n<h1>Extensions de classe<\/h1>\n<p>&nbsp;<br \/>\nLes extensions de classe permettent d&rsquo;ajouter \u00e0 une classe existante:<\/p>\n<ul>\n<li>de nouvelles propri\u00e9t\u00e9s calcul\u00e9es<\/li>\n<li>de nouveaux\u00a0constructeurs<\/li>\n<li>l&rsquo;abonnement \u00e0 un ou plusieurs protocoles<\/li>\n<\/ul>\n<p>Syntaxe:<\/p>\n<pre class=\"lang:swift decode:true \">extension UneClasse: UnProtocole, UnAutreProtocole {\n    \/\/ Programmation des protocoles\n    \/\/ Impl\u00e9mentation des nouvelles fonctionnalit\u00e9s\n}<\/pre>\n<p><strong><span style=\"color: #ff0000;\">Note<\/span><\/strong>: Il est possible d&rsquo;ajouter de nouvelles fonctionnalit\u00e9s \u00e0 une classe mais pas de surcharger les existantes.<br \/>\nPar exemple,<\/p>\n<pre class=\"lang:swift decode:true\">extension String {\n   var majuscule: String { return self.uppercaseString }\n}\nprintln(\"bonjour \u00e0 tous!\".majuscule)  \/\/ res.: BONJOUR \u00c0 TOUS!<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action \u00e0 r\u00e9aliser en laboratoire par l&rsquo;\u00e9tudiant:<\/strong><\/span><\/p>\n<ul>\n<li>Construire une classe &lsquo;Aquarium&rsquo; dont le constructeur re\u00e7oit un tableau de poissons et un volume exprim\u00e9 en gallon.<\/li>\n<li>Une m\u00e9thode &lsquo;quiSuisJe&rsquo; retourne la description de tous les poissons de l&rsquo;aquarium.<\/li>\n<\/ul>\n<pre class=\"lang:swift decode:true\">\/\/ Exemple d'utilisation de la classe Aquarium\n        let aquarium = Aquarium(individus: [\n            PoissonVolant(nomPoisson: \"Exocoetidae\", force: 99, hauteurDuVol: 66),\n            Poisson(nomPoisson: \"Bob\", force: 99)\n            ],\n            dimension:100)\n        println(aquarium.quiSuisJe())\n\/\/ R\u00e9sultat:\nJe suis un Aquarium de 100 gallon(s) avec les poissons suivants:\n------------------\nJe suis une poisson volant de type:Exocoetidae et je saute \u00e0 66 pied(s)\n------------------\nJe suis le poisson Bob et j'ai une force de 99<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Indice<\/strong><\/span>: Le type des \u00e9l\u00e9ments du tableau re\u00e7u par le constructeur est Array&lt;Poisson&gt;. \u00a0Ce tableau pourra stocker \u00a0toutes instances dont l&rsquo;anc\u00eatre est de type Poisson (incluant le PoissonVolant). \u00a0Cela s&rsquo;explique\u00a0par le concept de <a href=\"http:\/\/fr.wikipedia.org\/wiki\/Polymorphisme_(informatique)\">polymorphisme<\/a>.<br \/>\n&nbsp;<\/p>\n<hr \/>\n<h1>Constructeur de convenance<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Action 1.12<\/strong>\u00a0<\/span>&#8211;<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Constructeur de convenance\n    \/**\n    Construire un poisson pas de nom et de force entre deux nombres.\n    *\/\n    convenience init(deForceEntre:Int, etMax:Int){\n        self.init(nomPoisson:\"Pas de nom\", force: Int(arc4random_uniform(UInt32((etMax - deForceEntre) + 1))) + deForceEntre)\n    } \/\/ convenience init()\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.13<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivante \u00e0 la m\u00e9thode ViewDidLoad:<\/p>\n<pre class=\"lang:swift decode:true\">        let junior = Poisson(deForceEntre: 33, etMax: 44)\n        println( junior.quiSuisJe() )<\/pre>\n<p>&nbsp;<br \/>\nCe qui va afficher\u00a0dans la console:<\/p>\n<blockquote><p><b>viewDidLoad<\/b> <b>Je suis le constructeur de Poisson.<\/b><br \/>\n<b>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; <\/b><br \/>\n<b>Je suis le poisson Bob et j&rsquo;ai une force de 99<\/b><br \/>\n<b>Je suis le constructeur de Poisson.<\/b><br \/>\n<b>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; <\/b><br \/>\n<b>Je suis le poisson Pas de nom et j&rsquo;ai une force de 3<\/b><\/p><\/blockquote>\n<p><b>\u00a0<\/b><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 1.14<\/strong>\u00a0<\/span>&#8211; Ajoutons les deux m\u00e9thodes suivantes \u00e0 la classe Poisson<\/p>\n<pre class=\"lang:swift decode:true\">    \/**\n      M\u00e9thode pour \u00e9puiser artificiellement le poisson\n    *\/\n    func epuiserLePoisson(force:Int){\n        self.force -= force\n        if self.force &lt; 10 {\n            println(\"Le poisson \\(nomPoisson) est tr\u00e8s tr\u00e8s faible\")\n        }\n    } \/\/ epuiserLePoisson\n    \/**\n    M\u00e9thode pour nourrir le poisson\n    *\/\n    func nourrirLePoisson(nourriture:Int){\n        force += 2 * nourriture\n    } \/\/ nourrirLePoisson<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action 1.15<\/strong>\u00a0<\/span>&#8211; Ajoutons le code suivante \u00e0 la m\u00e9thode ViewDidLoad:<\/p>\n<pre class=\"lang:swift mark:2,3 decode:true\">        let unPoisson = Poisson(nomPoisson: \"Bob\", force: 99)\n        unPoisson.epuiserLePoisson(95)\n        unPoisson.nourrirLePoisson(40)\n        println(unPoisson.quiSuisJe())<\/pre>\n<p>&nbsp;<\/p>\n<blockquote><p><b>Je suis le constructeur de Poisson. <\/b><br \/>\n<b>Le poisson Bob est tr\u00e8s tr\u00e8s faible<\/b><br \/>\n<b>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/b><br \/>\n<b><\/b> <b>Je suis le poisson Bob et j&rsquo;ai une force de 84<\/b><\/p><\/blockquote>\n<p>&nbsp;<br \/>\n<a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/swift\/conceptual\/Swift_Programming_Language\/ClassesAndStructures.html#\/\/apple_ref\/doc\/uid\/TP40014097-CH13-XID_134\">R\u00e9f\u00e9rence Apple<\/a><br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/Projet-Aquarium-etape1.zip\">Projet-Aquarium-etape1<\/a><\/p>\n<hr \/>\n<h1><\/h1>\n<h1>\u00c9tape 2 &#8211; Protocole sur mesure<\/h1>\n<p>&nbsp;<br \/>\n\u00c0 l&rsquo;\u00e9tape pr\u00e9c\u00e9dente, nous avons ajout\u00e9 une m\u00e9thode pour affaiblir le poisson.<br \/>\nSous le seuil de force == 10, le poisson est plac\u00e9 en situation de danger de mort.<br \/>\nLe probl\u00e8me, c&rsquo;est que notre application n&rsquo;a aucune id\u00e9e de cet \u00e9tat de fait.<br \/>\nLes protocoles, sous Swift, permettent d&rsquo;indiquer \u00e0 une classe abonn\u00e9e qu&rsquo;un intervention est requise par la classe offrant le protocole.<br \/>\nPar exemple, si la classe Poisson propose un protocole nomm\u00e9 \u00ab\u00a0PoissonEtatDeSante\u00a0\u00bb et qu&rsquo;une autre classe du projet s&rsquo;abonne \u00e0 ce protocole alors cette derni\u00e8re sera avis\u00e9e des changements d&rsquo;\u00e9tats du poisson.<br \/>\n<a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/swift\/conceptual\/Swift_Programming_Language\/Protocols.html\">R\u00e9f\u00e9rence Apple<\/a><\/p>\n<hr \/>\n<h1><\/h1>\n<h1>D\u00e9finir et impl\u00e9menter un protocole sous Swift &#8211; 7\u00a0\u00e9tapes<\/h1>\n<h3><\/h3>\n<h3><span style=\"color: #1d9421;\"><span style=\"color: #000000;\">Dans la classe qui propose le protocole<\/span> <\/span><\/h3>\n<ul>\n<li><span style=\"color: #000000;\">\u00c9tape 1 &#8211; d\u00e9clarer le protocole<\/span><\/li>\n<li><span style=\"color: #000000;\">\u00e9tape 2 &#8211; d\u00e9clarer les m\u00e9thodes du protocole<\/span><\/li>\n<li><span style=\"color: #000000;\">\u00c9tape 3 &#8211; d\u00e9finir une propri\u00e9t\u00e9 &#8211; delegate &#8211; de type &lsquo;NomDuProtocole&rsquo;\u00a0pour y stocker le d\u00e9l\u00e9gu\u00e9 \u00e9ventuel<\/span><\/li>\n<li><span style=\"color: #000000;\">\u00c9tape 4 &#8211; g\u00e9rer le protocole<\/span><\/li>\n<\/ul>\n<h3><\/h3>\n<h3>Dans la classe qui s&rsquo;abonne au protocole<\/h3>\n<ul>\n<li><span style=\"color: #000000;\">\u00c9tape 5 &#8211; s&rsquo;abonner au protocole<\/span><\/li>\n<li><span style=\"color: #000000;\">\u00c9tape 6 &#8211; renseigner le delegate<\/span><\/li>\n<li><span style=\"color: #000000;\">\u00c9tape 7 &#8211; programmer les m\u00e9thodes du protocole<\/span><\/li>\n<\/ul>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.1<\/strong><\/span> &#8211; \u00c9tape 1 et 2 &#8211; Ajoutons le code suivant \u00e0 la classe Poisson.<\/p>\n<pre class=\"lang:swift decode:true\">\/\/ \u00c9tape 1 - d\u00e9clarer le protocole\nprotocol PoissonDelegate {\n    \/\/ \u00e9tape 2 - d\u00e9clarer les m\u00e9thodes du protocole\n    func poissonAFaim(sender:Poisson)\n}\n\/\/ Note - Avant: class Poisson { ...<\/pre>\n<p>&nbsp;<br \/>\n<strong><span style=\"color: #ff0000;\">Note<\/span>:<\/strong>\u00a0 Il est possible d&rsquo;identifier\u00a0des m\u00e9thodes d&rsquo;un protocole comme \u00e9tant facultatives. \u00a0Il faut alors d\u00e9clarer le protocole de la fa\u00e7on suivante:<\/p>\n<pre class=\"lang:swift decode:true \">@objc protocol UnProtocole {\n    optional func uneMethodeFacultative(count: Int) -&gt; Int\n    fun uneMethodeObligatoire(count: Int) -&gt; Int\n}<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.2<\/strong><\/span>\u00a0&#8211;\u00a0\u00c9tape 3 &#8211; Ajoutons le code suivant \u00e0 la classe Poisson.<\/p>\n<pre class=\"lang:swift mark:5 decode:true\">class Poisson {\n    \/\/ Propri\u00e9t\u00e9s\n    \/\/ \u00c9tape 3 - D\u00e9finir une propri\u00e9t\u00e9 - delegate - de type 'NomDuProtocole'\n    \/\/\/ Propri\u00e9t\u00e9 pour stocker le d\u00e9l\u00e9gu\u00e9 \u00e9ventuel de l'instance Poisson\n    var delegate:PoissonDelegate?<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.3<\/strong><\/span>\u00a0&#8211;\u00a0\u00c9tape 4 &#8211; Ajoutons le code suivant \u00e0 la classe Poisson &#8211; <span style=\"color: #ff0000;\">seulement la ligne 6<\/span>.<\/p>\n<pre class=\"lang:swift mark:6 decode:true\">    func epuiserLePoisson(force:Int){\n        self.force -= force\n        if self.force &lt; 10 {\n             println(\"Le poisson \\(nomPoisson) est tr\u00e8s tr\u00e8s faible - force &lt; 10\")\n            \/\/ \u00c9tape 4 - g\u00e9rer le protocole\n            delegate?.poissonAFaim(self)\n        }  \/\/ self.force &lt; 10\n    } \/\/ epuiserLePoisson<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.4<\/strong><\/span>\u00a0&#8211;\u00a0\u00c9tape 5 &#8211; Ajoutons le code suivant \u00e0 la classe abonn\u00e9e<\/p>\n<pre class=\"lang:swift decode:true\" title=\"Ajouter ', PoissonDelagate' \u00e0 la suite de la super classe\">\/\/ \u00c9tape 5 - s'abonner au protocole\nclass ViewController: UIViewController, PoissonDelegate{<\/pre>\n<p>&nbsp;<br \/>\n.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.5<\/strong><\/span>\u00a0&#8211;\u00a0\u00c9tape 5 &#8211; Ajoutons le code suivant \u00e0 la classe abonn\u00e9e\u00a0&#8211; <span style=\"color: #ff0000;\">seulement la ligne 5<\/span>.<\/p>\n<pre class=\"lang:swift mark:5 decode:true\">    override func viewDidLoad() {\n        super.viewDidLoad()\n        unPoisson = Poisson(nomPoisson: \"Bob\", force: 99)\n        \/\/ \u00c9tape 6 - renseigner le delegate\n        unPoisson.delegate = self<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.6<\/strong><\/span>\u00a0&#8211;\u00a0\u00c9tape 5 &#8211; Ajoutons le code suivant \u00e0 la classe abonn\u00e9e<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ \u00c9tape 7 - Programmer les m\u00e9thodes du protocole\n    func poissonAFaim(sender: Poisson) {\n        println(\"Le poisson \\(sender.nomPoisson) a faim, je vais donc le nourrir!\")\n        sender.nourrirLePoisson(20)\n    } \/\/ poissonAFaim<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 2.7<\/strong><\/span>\u00a0&#8211; Ex\u00e9cutons l&rsquo;application<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2060\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.29-800x176.png\" alt=\"aquarium.29\" width=\"800\" height=\"176\" \/><br \/>\n&nbsp;<br \/>\n<strong style=\"color: #ff0000;\">Action \u00e0 r\u00e9aliser en laboratoire par l\u00a0\u00bb\u00e9tudiant:<\/strong><\/p>\n<ul>\n<li>Ajoutez la m\u00e9thode &lsquo;poissonEstMort&rsquo; au protocole PoissonDelegate.<\/li>\n<li>Lorsque la force du poisson est &lt;= 0, envoyez le message \u00ab\u00a0poissonEstMort\u00a0\u00bb \u00e0 la classe abonn\u00e9e au protocole.<\/li>\n<\/ul>\n<p>&nbsp;<br \/>\nDans la classe abonn\u00e9e:<\/p>\n<ul>\n<li>Faites passer \u00e0 z\u00e9ro la force d&rsquo;un de vos poissons.<\/li>\n<li>En utilisant le protocole PoissonDelegate, affichez le nom du poisson mort.<\/li>\n<li>Soustrayez le nombre de poissons courants de un et affichez le r\u00e9sultat sur\u00a0la sc\u00e8ne.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<h1><span style=\"color: #ff0000;\">point de rep\u00e8re pour la mise \u00e0 jour<\/span><\/h1>\n<hr \/>\n<p>&nbsp;<br \/>\n&nbsp;<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/Projet-Aquarium-etape2.zip\">Projet-Aquarium-etape2<\/a><\/p>\n<hr \/>\n<h1><\/h1>\n<h1>\u00c9tape 3 &#8211; Classe\u00a0Poisson \u00e0 partir de UIImageView<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.1<\/strong><\/span>\u00a0&#8211; Dans la classe Poisson, ajoutons le code suivant<br \/>\n<strong>Note<\/strong>: \u00c0 cette \u00e9tape, l\u00a0\u00bbimage du poisson sera cod\u00e9e en dur.<\/p>\n<pre class=\"lang:swift decode:true\">\/\/ 1 - Importer le frameWork UIKit\nimport UIkit\n\/\/ 2 - Classe Poisson \u00e9tend UIImageView\nclass Poisson:UIImageView {<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: Suite \u00e0 l&rsquo;ajout d&rsquo;une classe \u00e0 \u00e9tendre dans la d\u00e9claration de la classe Poisson, nous obtenons l&rsquo;erreur suivante:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2024\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.10-800x280.png\" alt=\"aquarium.10\" width=\"800\" height=\"280\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.2<\/strong><\/span>\u00a0&#8211;\u00a0Confirmons le Fix-it*, ce qui ajoutera le code suivant \u00e0 la classe:<\/p>\n<pre class=\"lang:swift decode:true\">    \/**\n      Cette m\u00e9thode est obligatoire lorsque la super classe est de type 'Fondation'\n    *\/\n    required init(coder aDecoder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }<\/pre>\n<p>*Il faudra aussi faire cette correction avec la classe PoissonVolant.<br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: \u00a0Il y a encore une erreur \u00e0 corriger &#8211; l&rsquo;appel du constructeur de la super classe.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2025\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.11.png\" alt=\"aquarium.11\" width=\"718\" height=\"148\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.3<\/strong><\/span>\u00a0&#8211; Modifions le constructeur de la classe Poisson pour y ajouter l\u00a0\u00bbappel du constructeur de la super classe.<\/p>\n<pre class=\"lang:swift decode:true\">\/\/ 3 - Modification du constructeur de la classe Poisson\n    \/\/ Constructeur\n    \/**\n      Construire un poisson \u00e0 partir d'un nom et d'une force\n    *\/\n    init(nomPoisson:String, force:Int) {\n       println(\"Je suis le constructeur de Poisson.\")\n       self.nomPoisson  = nomPoisson\n       self.force       = force\n       self.nomImage    = \"n\/a\"\n       \/\/ \u00c9tape 3.3 - Appel de super.init()\n       \/\/ Note:  Il faut renseigner les propri\u00e9t\u00e9s locales\n       \/\/ avant l'appel de super.init()\n       \/\/ Il faut utiliser le constructeur de la super classe\n       \/\/ Il n'est pas possible d'utiliser un init de convenance de la super classe (\u00e0 valider sous 6.1).\n       \/\/ Le contructeur de UIImageView est:  init(image: UIImage!)\n       \/\/ Par contre, il ne permet pas de pr\u00e9ciser une taille pour l'image.\n       \/\/ Nous allons donc faire appel au contructeur de la super classe de UIImageView C-A-D, UIView(frame: CGRect)\n       \/\/\n       \/\/ Cr\u00e9er une View \u00e0 la position (20,150) de dimension (100, 50)\n       super.init(frame: CGRectMake(20, 150, 100, 50))\n       image = UIImage(named: \"p13-frame-1.gif\")\n    } \/\/ init()<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.3b<\/strong><\/span>\u00a0&#8211; \u00a0Ajoutons le poisson \u00e0 la vue de la sc\u00e8ne.<\/p>\n<pre class=\"lang:swift decode:true \">        view.addSubview(unPoisson)\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.4<\/strong><\/span>\u00a0&#8211; \u00a0Testons l&rsquo;application.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2026\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.12-326x600.png\" alt=\"aquarium.12\" width=\"326\" height=\"600\" \/><br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: La classe poisson poss\u00e8de maintenant une interface visuelle de type \u00ab\u00a0UIView\u00a0\u00bb et peut \u00eatre ajout\u00e9e \u00e0 la vue d&rsquo;une sc\u00e8ne.<\/p>\n<hr \/>\n<h1>Animer une s\u00e9rie d&rsquo;image<\/h1>\n<p>&nbsp;<br \/>\nLa classe &lsquo;UIImage&rsquo; propose des m\u00e9thodes et des propri\u00e9t\u00e9s pour animer une s\u00e9quence d&rsquo;images.<br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.5<\/strong><\/span>\u00a0&#8211; \u00a0Ajoutons le code suivant\u00a0\u00e0 la fin du constructeur de\u00a0la classe Poisson.<\/p>\n<pre class=\"lang:swift decode:true\">        \/\/ Cr\u00e9er l'animation \u00e0 partir d'une suite d'images\n        var images:[UIImage] = []\n        \/\/ Note: Il y a 8 images pour l'animation du poisson P13\n        for i in 1...8 {\n            \/\/ Note: Xcode 6.1 - UIImage(named:) retourne une optionnelle.\n            images.append(UIImage(named:\"p13-frame-\\(i).gif\"))\n        }\n        animationImages = images  \/\/ Un tableau d'images pour l'animation\n        animationDuration = 1.5   \/\/ La dur\u00e9e de l'animation\n        startAnimating()          \/\/ D\u00e9marrer l'animation\n\/\/    } \/\/ init()<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.6<\/strong><\/span>\u00a0&#8211; \u00a0Testons l&rsquo;application<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: Le poisson devrait maintenant \u00eatre anim\u00e9 \u00e0 l&rsquo;\u00e9cran.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2028\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/clownfish.gif\" alt=\"clownfish\" width=\"166\" height=\"85\" \/><br \/>\n<span style=\"color: #ff0000;\"><strong>Note:\u00a0<span style=\"color: #000000;\">Si le nom du dossier contenant les images de l&rsquo;animation se termine par &lsquo;.atlas&rsquo; Xcode va alors cr\u00e9er automatiquement une &lsquo;sprite sheet&rsquo;.<\/span><\/strong><\/span><br \/>\nExemple d&rsquo;une sprite sheet:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2130\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/2D_Tikiman_SpriteSheet.jpg\" alt=\"2D_Tikiman_SpriteSheet\" width=\"430\" height=\"320\" \/><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.7<\/strong><\/span>\u00a0&#8211; \u00a0Ajoutons un nouveau constructeur, \u00e0 notre classe Poisson, qui recevra le nom de l&rsquo;image, la\u00a0position, la dimension et le d\u00e9l\u00e9gu\u00e9 du protocole PoissonDelegate.<br \/>\n&nbsp;<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Constructeur\n    \/**\n    Construire un poisson anim\u00e9 \u00e0 x,y hauteur et largeur et d\u00e9l\u00e9gu\u00e9\n    *\/\n    init(nomPoisson:String, nomImage:String, nbImages:Int, posX:CGFloat, posY:CGFloat, largeur:CGFloat, hauteur:CGFloat, leDelegate:PoissonDelegate) {\n        println(\"Je suis le constructeur de \\(nomPoisson).\")\n        self.nomPoisson  = nomPoisson\n        self.force       = 20\n        self.nomImage    = nomImage\n        delegate         = leDelegate\n        \/\/ Note:  Il faut renseigner les propri\u00e9t\u00e9s locales\n        \/\/ avant l'appel super.init()\n        super.init(frame: CGRectMake(posX , posY, largeur, hauteur))\n        \/\/ Image sans anime - poisson mort\n        image = UIImage(named: \"mort.png\")\n        \/\/ Cr\u00e9er l'animation \u00e0 partir d'une suite d'images\n        var images:[UIImage] = []\n        for i in 1...nbImages {\n            images.append(UIImage(named: \"\\(nomImage)-frame-\\(i).gif\")!)\n        } \/\/ for nbImages\n        animationImages = images\n        animationDuration = 1.5\n        startAnimating()\n    } \/\/ init()<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.8<\/strong><\/span>\u00a0&#8211; Et rempla\u00e7ons le code de\u00a0viewDidLoad par:<\/p>\n<pre class=\"lang:swift decode:true\">    override func viewDidLoad() {\n        println(\"viewDidLoad\")\n        super.viewDidLoad()\n        \/\/ TODO: Ajouter des bulles\n        let x = Poisson(nomPoisson: \"Poisson 1\", nomImage: \"p11\", nbImages: 8, posX: 150, posY: 250, largeur: 100, hauteur: 50, leDelegate: self)\n        x.epuiserLePoisson(99)\n        view.addSubview(x)\n        \/\/ Pr\u00e9parer l'aquarium\n        commencerLaPartie()\n    } \/\/ viewDidLoad<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.9<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2029\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.13-327x600.png\" alt=\"aquarium.13\" width=\"327\" height=\"600\" \/><br \/>\n&nbsp;<br \/>\n<strong>Note<\/strong>: Remarquez que le poisson r\u00e9pond au protocole PoissonDelegate.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2030\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.14.png\" alt=\"aquarium.14\" width=\"628\" height=\"336\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.10<\/strong><\/span>\u00a0&#8211; \u00a0Cr\u00e9ons plusieurs poissons, dans la m\u00e9thode &lsquo;ajouterPoissons&rsquo; \u00e0 partir des enregistrements du tableau &lsquo;modelesPoisson&rsquo;.<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: \u00a0Il faut effacer le poisson que nous avons cr\u00e9\u00e9 dans ViewDidLoad.<\/p>\n<pre class=\"lang:swift decode:true\">    \/**\n    Cr\u00e9er des poissons et les ajouter \u00e0 la sc\u00e8ne principale.\n    *\/\n    func ajouterLesPoissons(quantite:Int){\n        println(\"ajouterLesPoissons\")\n        \/\/ Poisson 1, pour tester le protocole\n        let x = Poisson(nomPoisson: \"Poisson 1\", nomImage: \"p11\", nbImages: 8, posX: 50, posY: 180, largeur: 100, hauteur: 50, leDelegate: self)\n        x.epuiserLePoisson(99)\n        view.addSubview(x)\n        \/\/ Ou bien directement, sans passer par une variable.\n        view.addSubview(Poisson(nomPoisson: \"Poisson 2\", nomImage: \"p11\", nbImages: 8, posX: 50, posY: 120, largeur: 75 , hauteur: 37, leDelegate: self))\n        view.addSubview(Poisson(nomPoisson: \"Poisson 3\", nomImage: \"p11\", nbImages: 8, posX: 130, posY: 120, largeur: 100 , hauteur: 50, leDelegate: self))\n        view.addSubview(Poisson(nomPoisson: \"Poisson 4\", nomImage: modelesPoisson[2][\"nom\"]!, nbImages: (modelesPoisson[2][\"nbImages\"]!).toInt()!, posX: 75, posY:400, largeur: 100 , hauteur: 50, leDelegate: self))\n        view.addSubview(Poisson(nomPoisson: \"Poisson 5\", nomImage: modelesPoisson[2][\"nom\"]!, nbImages: (modelesPoisson[2][\"nbImages\"]!).toInt()!, posX: 160, posY: 450, largeur: 100 , hauteur: 50, leDelegate: self))\n        view.addSubview(Poisson(nomPoisson: \"Poisson 6\", nomImage: modelesPoisson[1][\"nom\"]!, nbImages: (modelesPoisson[1][\"nbImages\"]!).toInt()!, posX: 220, posY: 290, largeur: 100 , hauteur: 60, leDelegate: self))\n    } \/\/ ajouterLesPoissons<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: \u00a0Il faut aussi ajuster le nombre de poissons de d\u00e9part \u00e0 6:<\/p>\n<pre class=\"lang:swift decode:true \">    let nbPoissonsDepart            = 6<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 3.11<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2032\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.15-326x600.png\" alt=\"aquarium.15\" width=\"326\" height=\"600\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2033\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.16.png\" alt=\"aquarium.16\" width=\"583\" height=\"405\" \/><br \/>\n&nbsp;<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/Projet-Aquarium-etape3.zip\">Projet-Aquarium-etape3<\/a><\/p>\n<hr \/>\n<h1>\u00c9tape 4 &#8211; Donner vie au Poisson: NSTimer<\/h1>\n<p>\u00c0 cette \u00e9tape, nous donnerons vie \u00e0 notre poisson grace \u00e0 un temporisateur (NSTimer) de 2 secondes. \u00a0\u00c0 chaque intervalle, il sera possible d&rsquo;ex\u00e9cuter du code dans le but de modifier certains param\u00e8tres de la classe. Par exemple, le niveau d&rsquo;\u00e9nergie du poisson, son \u00e9tat (vivant\/mort), &#8230;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.1<\/strong><\/span>\u00a0&#8211; Ajoutons le code suivant \u00e0 la classe Poisson.<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Propri\u00e9t\u00e9s de la classe Poisson\n    var unTimer = NSTimer()\n    let intervalleTemps:NSTimeInterval = 2\n    \/\/ Ajouter ces lignes \u00e0 la fin du constructeur\n        unTimer = NSTimer.scheduledTimerWithTimeInterval(intervalleTemps, target: self, selector: Selector(\"gererLeProtocoleDelegate:\"), userInfo: nil, repeats: true)\n     } \/\/ init\n   \/\/ Ajouter cette m\u00e9thode \u00e0 la classe Poisson\n    \/**\n    M\u00e9thode de gestion PoissonDelegate\n    *\/\n    func gererLeProtocoleDelegate(timer: NSTimer){\n        \/\/println(\"testerDelegate de \\(nom)\")\n        let impact = Int(arc4random_uniform(5))\n        force-=impact\n        delegate?.poissonAFaim(self)\n    } \/\/ testerDelegate\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.2<\/strong><\/span>\u00a0&#8211; Ajoutons la valeur de la force dans la trace de la m\u00e9thode poissonAFaim.<\/p>\n<pre class=\"lang:swift decode:true \">       println(\"Le poisson \\(sender.nomPoisson), force de:\\(sender.force) a faim, je vais donc le nourrir!\")\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.3<\/strong><\/span>\u00a0&#8211; Testons l\u00a0\u00bbapplication.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2039\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.18-800x475.png\" alt=\"aquarium.18\" width=\"800\" height=\"475\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.4<\/strong><\/span>\u00a0&#8211; Ajoutons, dans la classe Poisson, la d\u00e9claration de deux m\u00e9thodes au protocole PoissonDelegate.<\/p>\n<pre class=\"lang:swift decode:true\">func poissonEnDangerDeMort(sender:Poisson)\nfunc poissonEstMort(sender:Poisson)<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.5<\/strong><\/span>\u00a0&#8211; Modifions la m\u00e9thode\u00a0gererLeProtocoleDelegate.<\/p>\n<pre class=\"lang:swift mark:6-14 decode:true\">    func gererLeProtocoleDelegate(timer: NSTimer){\n        let impact = Int(arc4random_uniform(5))\n        force-=impact\n        delegate?.poissonAFaim(self)\n        if force &lt; seuilDangerDeMort {\n            delegate?.poissonEnDangerDeMort(self)\n            stopAnimating()\n        } \/\/ force &lt; 10\n        if force &lt;= 0 {\n            unTimer.invalidate()\n            \/\/timerDeplacement.invalidate()\n            delegate?.poissonEstMort(self)\n        } \/\/ force &lt;= 0\n    } \/\/ testerDelegate<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: La classe abonn\u00e9e n&rsquo;est plus conforme au protocole PoissonDelegate.<br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.6<\/strong><\/span>\u00a0&#8211; Ajoutons les deux m\u00e9thodes suivantes \u00e0 la classe ViewController.<\/p>\n<pre class=\"lang:swift decode:true\">    func poissonEnDangerDeMort(sender: Poisson) {\n        println(\"\\(sender.nomPoisson) a une force de \\(sender.force) et il va mourrir de faim!\")\n    }\n    func poissonEstMort(sender: Poisson) {\n        println(\"\\(sender.nomPoisson) est mort\")\n    } \/\/ poissonEstMort<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.7<\/strong><\/span>\u00a0&#8211; Cessons de nourrir le poisson lorsqu&rsquo;il a faim.<\/p>\n<pre class=\"lang:swift mark:3 decode:true\">    func poissonAFaim(sender: Poisson) {\n        println(\"Le poisson \\(sender.nomPoisson), force de:\\(sender.force) a faim, je vais donc le nourrir!\")\n        \/\/ sender.nourrirLePoisson(20)\n    } \/\/ poissonAFaim<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.8<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2040\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.19-326x600.png\" alt=\"aquarium.19\" width=\"326\" height=\"600\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2041\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.20-800x542.png\" alt=\"aquarium.20\" width=\"800\" height=\"542\" \/><br \/>\n\u00c9ventuellement,\u00a0les poissons vont tous mourrir.<br \/>\nIl faudrait les enlever de la sc\u00e8ne \u00e0 leur d\u00e9c\u00e8s et g\u00e9rer l&rsquo;indicateur de poissons restants.<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.9<\/strong><\/span>\u00a0&#8211; Effa\u00e7ons le poisson mort.<\/p>\n<pre class=\"lang:swift mark:4-6 decode:true\">\/\/ ViewController.swift\n    func poissonEstMort(sender: Poisson) {\n        println(\"\\(sender.nomPoisson) est mort\")\n        \/\/sender.unTimer.invalidate()\n        sender.removeFromSuperview()\n        nbPoissons--\n        actualiserLabelNBPoissons()\n    } \/\/ poissonEstMort<\/pre>\n<p><strong><span style=\"color: #339966;\">Note<\/span><\/strong>: \u00a0L&rsquo;instance de la classe poisson va persister m\u00eame suite \u00e0 un .removeFromSuperview car le NSTimer maintient \u00a0une r\u00e9f\u00e9rence \u00e0 la m\u00e9thode\u00a0gererLeProtocoleDelegate de la classe poisson. \u00a0Le message &lsquo;poissonEstMort&rsquo; va continuer \u00e0 \u00eatre envoy\u00e9 \u00e0 la classe abonn\u00e9e aussi longtemps que le &lsquo;Timer&rsquo; va \u00eatre actif.<br \/>\nPour d\u00e9sactiver le Timer il faut appeler la m\u00e9thode &lsquo;invalidate()&rsquo; de ce dernier.<\/p>\n<hr \/>\n<h1><\/h1>\n<h1>Le destructeur d&rsquo;une classe &#8211; deinit<\/h1>\n<p><span style=\"color: #ff0000;\"><strong>Action 4.9b<\/strong><\/span>\u00a0&#8211; Ajoutons la m\u00e9thode suivante \u00e0 la classe Poisson.<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Destructeur de la classe Poisson\n    \/\/ Faire le m\u00e9nage ici.  Par exemple, fermer des connexions, ...\n    \/\/ Attention: l'objet ne sera pas d\u00e9truit s'il y a des Timers qui tournent.\n    deinit{\n        println(\"Je suis le fossoyeur de l'objet \\(nomPoisson)\")\n    }  \/\/ deinit\n<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>Action 4.10<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application<br \/>\n[table]<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2042\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.22-328x600.png\" alt=\"aquarium.22\" width=\"328\" height=\"600\" \/>, <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2043\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.23-326x600.png\" alt=\"aquarium.23\" width=\"326\" height=\"600\" \/><br \/>\n[\/table]<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.11<\/strong><\/span>\u00a0&#8211; Affichons le panneau de fin de partie lorsque le nombre de poissons sera == 0.<br \/>\n&nbsp;<\/p>\n<pre class=\"lang:swift mark:6-7 decode:true\">    func poissonEstMort(sender: Poisson) {\n        println(\"\\(sender.nomPoisson) est mort\")\n        sender.removeFromSuperview()\n        nbPoissons--\n        actualiserLabelNBPoissons()\n        if nbPoissons == 0 {\n            finPartie.hidden = false\n        } \/\/ if nbPoissons == 0\n    } \/\/ poissonEstMort<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.12<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2045\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.24-326x600.png\" alt=\"aquarium.24\" width=\"326\" height=\"600\" \/><br \/>\n&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 4.13<\/strong><\/span>\u00a0&#8211; Analysons\u00a0la m\u00e9thode &lsquo;commencerLaPartie&rsquo;<\/p>\n<pre class=\"lang:swift decode:true \">    func commencerLaPartie(){\n        println(\"commencerLaPartie\")\n        \/\/ Masquer la View de fin de la partie\n        finPartie.hidden = true\n        nourritureDisponible = maximumNourritureDisponible\n        actualiserProgressViewQuantNourriture()\n        nbPoissons = nbPoissonsDepart\n        actualiserLabelNBPoissons()\n        \/\/ Ajouter des poissons\n        ajouterLesPoissons(nbPoissons)\n    } \/\/ commencerLaPartie<\/pre>\n<p>&nbsp;<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/Projet-Aquarium-etape4.zip\">Projet-Aquarium-etape4<\/a><\/p>\n<hr \/>\n<h1>\u00c9tape 5 &#8211; Interagir avec les poissons<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 5.1<\/strong><\/span>\u00a0&#8211; Modifions la propri\u00e9t\u00e9 &lsquo;userInteractionEnabled&rsquo; de la classe poisson, pour permettre \u00e0 UIImageView de recevoir les interactions de l&rsquo;utilisateur.<\/p>\n<pre class=\"lang:swift mark:4 decode:true\">\/\/ Constructeur de la classe Poisson\n\/\/ init(nomPoisson:String, nomImage:String, posX:CGFloat, posY:CGFloat, taille:CGFloat, leDelegate:PoissonDelegate, nbImages:Int) {\n   userInteractionEnabled = true\n\/\/ } \/\/ init<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 5.2<\/strong><\/span>\u00a0&#8211; \u00a0Nourrir le poisson suite \u00e0 une gestuelle<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ \u00c9tape 5 - Ajouter la m\u00e9thode suivante:\n    \/\/ M\u00e9thode ex\u00e9cut\u00e9e lorsque l'\u00e9cran est touch\u00e9.\n    \/\/ touch.view pointe sur la View qui a re\u00e7u l'\u00e9v\u00e9nement\n    override func touchesBegan(touches: Set&lt;NSObject&gt;, withEvent event: UIEvent) {\n        \/\/ println(touches.anyObject())\n        super.touchesBegan(touches, withEvent: event)\n        let touch : UITouch = touches.first as! UITouch\n        \/*\n        if touch.view.isKindOfClass(Poisson)\n        {\n        }\n        *\/\n        if let poissonCourant = touch.view as? Poisson {\n            println(\"C'est un poisson!\")\n            if nourritureDisponible &gt;= unePortionDeNourriture {\n                poissonCourant.nourrirLePoisson(unePortionDeNourriture)\n                nourritureDisponible -= unePortionDeNourriture\n                actualiserProgressViewQuantNourriture()\n            }\n        } \/\/ if touch.view as? Poisson\n    } \/\/ touchesBegan\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 5.3<\/strong><\/span>\u00a0&#8211;\u00a0Modifions la classe Poisson.<\/p>\n<pre class=\"lang:swift mark:5-8 decode:true\">    \/**\n    M\u00e9thode pour nourrir le poisson\n    *\/\n    func nourrirLePoisson(nourriture:Int){\n        force = nourriture\n        if force &gt; seuilDangerDeMort {\n            startAnimating()\n        }\n    } \/\/ nourrirLePoisson<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 5.4<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application (regardez l&rsquo;indicateur de nourriture descendre et les poissons revenir \u00e0 la vie)<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>:\u00a0\u00a0la m\u00e9thode <strong>ajouterNourriture()<\/strong> est d\u00e9j\u00e0 fonctionnelle.<br \/>\n&nbsp;<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2076 size-full\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/d2mip.gif\" alt=\"d2mip\" width=\"260\" height=\"442\" \/><br \/>\n&nbsp;<br \/>\n<a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/Projet-Aquarium-etape5.zip\">Projet-Aquarium-etape5<\/a><\/p>\n<hr \/>\n<h1>\u00c9tape 6 &#8211; \u00c0 r\u00e9aliser en\u00a0laboratoire<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: Voici comment masquer la barre d&rsquo;\u00e9tat du t\u00e9l\u00e9phone<\/p>\n<pre class=\"lang:swift decode:true\">override func prefersStatusBarHidden() -&gt; Bool {\n    return true\n}<\/pre>\n<p>&nbsp;<br \/>\nIl faut cr\u00e9er une classe Plante qui:<\/p>\n<ul>\n<li>Anime le mouvement d&rsquo;une plante\u00a0\u00e0 l&rsquo;\u00e9cran &#8211; les images sont cod\u00e9es en dur dans la classe &#8211;\u00a0\u00e0 partir des images suivantes:\u00a0<span style=\"color: #0000ff;\"><a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/1sur3.anime_.plante.zip\"><span style=\"color: #0000ff;\">1sur3.anime.plante<\/span><\/a><\/span>.<\/li>\n<li>Propose le protocole PlanteOxygene avec la m\u00e9thode planteProduitOxygene.<\/li>\n<li>Lance la m\u00e9thode\u00a0planteProduitOxygene \u00e0 toutes les secondes (gestion du protocole) \u00a0avec un quantit\u00e9 d&rsquo;oxyg\u00e8ne al\u00e9atoire entre 1 et 5.<\/li>\n<\/ul>\n<p>Il faut:<\/p>\n<ul>\n<li>Ajouter 2 plantes \u00e0 la sc\u00e8ne principale.<\/li>\n<li>Abonner la sc\u00e8ne au protocole\u00a0PlanteOxygene.<\/li>\n<li>Programmer la m\u00e9thode\u00a0planteProduitOxygene pour ajouter la\u00a0quantit\u00e9 d&rsquo;oxyg\u00e8ne comme nourriture \u00e0 l&rsquo;aquarium.<\/li>\n<li>Arr\u00eater le Timer de la plante\u00a0et retirer les plantes (voir code qui suit)\u00a0\u00e0 la fin de la partie.<\/li>\n<li>Tester l&rsquo;application.<\/li>\n<\/ul>\n<pre class=\"lang:swift decode:true \">\/\/ Effacer les plantes\nfor unObjetDeLascene in view.subviews {\n  if let plante = unObjetDeLascene as? Plante {\n    plante.unTimer.invalidate()\n    plante.removeFromSuperview()\n  }\n} \/\/ for unObjetDeLascene\n<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h1>\u00c9tat 7\u00a0&#8211; D\u00e9placement du poisson, son et twitter<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.1<\/strong><\/span>\u00a0&#8211; \u00a0Ajoutons des propri\u00e9t\u00e9s \u00e0 la classe poisson<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ \u00c9tape 7\n    var timerDeplacement = NSTimer()\n    let intervalleTempsDeplacement:NSTimeInterval = 1\/15\n    var _largeurEcran:CGFloat = 0\n    var _hauteurEcran:CGFloat = 0<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.2<\/strong><\/span>\u00a0&#8211; Ajoutons une m\u00e9thode pour obtenir la dimension de l&rsquo;appareil<\/p>\n<pre class=\"lang:swift decode:true\">    \/\/ Etape 7\n    func determinerDimensionsEcran(){\n        \/\/ D\u00e9terminer la r\u00e9solution de l'appareil\n        let screenRect:CGRect = UIScreen.mainScreen().bounds\n        _largeurEcran = screenRect.width\n        _hauteurEcran = screenRect.height\n        println(screenRect)\n    } \/\/ determinerDimensionsEcran<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.3<\/strong><\/span>\u00a0&#8211; Ajoutons\u00a0le code suivant au\u00a0constructeur de Poisson<\/p>\n<pre class=\"lang:swift decode:true\">        \/\/ \u00c9tape 7 - Cr\u00e9er un NSTimer pour le d\u00e9placement du poisson\n        timerDeplacement = NSTimer.scheduledTimerWithTimeInterval(intervalleTempsDeplacement, target: self, selector: Selector(\"deplacerObjet:\"), userInfo: nil, repeats: true)\n        determinerDimensionsEcran()\n<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.4<\/strong><\/span>\u00a0&#8211; Calculons la nouvelle position du poisson<br \/>\n&nbsp;<\/p>\n<pre class=\"lang:swift decode:true\">    func deplacerObjet(timer: NSTimer){\n        let vitesse:CGFloat = 3\n        let largeurImage = self.frame.width \/ 2\n        \/\/ Note: Les poissons vont de droite \u00e0 gauche, sauf pour p12\n        let _direction:CGFloat =  nomImage == \"p12\" ? -1 : 1\n        var position = self.center\n        position.x = self.center.x - (vitesse * _direction)\n        \/\/ Ajuster la position si le poisson sort de l'\u00e9cran\n        if (_direction == 1 &amp;&amp; (position.x + largeurImage) &lt; 0){\n            \/\/ \u00c0 la fin, ajuster avec la largeur du view\n            position.x = _largeurEcran + largeurImage\n        }\n        if (_direction == -1 &amp;&amp; (position.x - largeurImage) &gt; _largeurEcran){\n            \/\/ Au debut, ajuster avec la largeur du view\n            position.x = -largeurImage\n        }\n        \/\/ Renseigner la nouvelle position du poisson\n        self.center = position;\n    } \/\/ deplacerObjet<\/pre>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.5<\/strong><\/span>\u00a0&#8211; Testons l&rsquo;application<br \/>\n<span style=\"color: #ff0000;\"><strong>Note<\/strong><\/span>: \u00a0Voici comment programmer\u00a0un mouvement un peu plus naturel aux poissons:<\/p>\n<pre class=\"lang:swift decode:true \">position.y = sin(self.center.x \/ 100) * 30 + postionYDepart\n<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h1><\/h1>\n<h1>Ajout de bandes sonores<\/h1>\n<p>&nbsp;<br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.5<\/strong><\/span>\u00a0&#8211; Ajoutons les fichiers suivants au projet:\u00a0<a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium.sons_.zip\">aquarium.sons<\/a><br \/>\n<span style=\"color: #ff0000;\"><strong>Action 7.6<\/strong><\/span>\u00a0&#8211; Ajoutons le code suivant au projet.<\/p>\n<pre class=\"lang:swift decode:true\">\/\/ 1 - Importer le kit AudioVideo\nimport AVFoundation\n\/\/ 2 - \u00c0 ajouter dans la zone de d\u00e9finition des propri\u00e9t\u00e9s de la classe ViewController\n    var playerTrameSonoreAquarium       = AVAudioPlayer()\n\/\/ 3 - M\u00e9thode \u00e0 ajouter dans la classe ViewController\n    func ChargerTramesSonores(){\n        \/\/ Permettre la lecture en arri\u00e8re plan.\n        \/\/ AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)\n        \/\/ AVAudioSession.sharedInstance().setActive(true, error: nil)\n        let URLTrameSonoreAquarium = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(\"eau\", ofType: \"mp3\")!)\n            var error:NSError?\n            playerTrameSonoreAquarium = AVAudioPlayer(contentsOfURL: URLTrameSonoreAquarium, error: &amp;error)\n            playerTrameSonoreAquarium.prepareToPlay()     \/\/ Charger le fichier son en m\u00e9moire\n            playerTrameSonoreAquarium.numberOfLoops = -1  \/\/ Boucle \u00e0 l'infini avec une valeur n\u00e9gative\n            playerTrameSonoreAquarium.volume = 0.2\n    }  \/\/ ChargerTramesSonores\n\/\/ 4 - \u00c0 ajouter dans la m\u00e9thode ViewDidLoad()\n        ChargerTramesSonores()\n\/\/ 5 - \u00c0 ajouter dans la m\u00e9thode commercerLaPartie()\n        playerTrameSonoreAquarium.play()<\/pre>\n<p><a href=\"\/xcode\/wp-content\/uploads\/2014\/10\/Projet-Aquarium-fin-etape-7-sans-parties-labo.zip\">Projet-Aquarium-fin-etape-7-sans-parties-labo<\/a><\/p>\n<hr \/>\n<h1><\/h1>\n<h1>8 &#8211; Laboratoire<\/h1>\n<h3><span style=\"color: #ff0000;\">\u00c0 faire en laboratoire par l&rsquo;\u00e9tudiant:<\/span><\/h3>\n<ul>\n<li><span style=\"color: #ff0000;\">Ajouter les sons aux endroits suivants:<\/span><\/li>\n<\/ul>\n<ol>\n<li>mort.mp3 &#8211; \u00e0 la mort d&rsquo;un poisson.<\/li>\n<li>tick.mp3 &#8211; lorsqu&rsquo;un poisson est nourri .<\/li>\n<li>buzzer.mp3 &#8211; s&rsquo;il n&rsquo;y a pas assez d&rsquo;oxyg\u00e8ne \u00e0 l&rsquo;achat de nourriture. \u00a0L&rsquo;achat de nourriture co\u00fbte 50 oxyg\u00e8nes.<\/li>\n<li>buzzer.mp3 &#8211; s&rsquo;il n&rsquo;y a pas assez de nourriture pour nourrir le poisson touch\u00e9.<\/li>\n<li>achat.mp3 &#8211; \u00e0 l&rsquo;achat de nourriture.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ul>\n<li><span style=\"color: #ff0000;\">Modifier la fen\u00eatre de fin de partie pour quelle \u00a0soit identique \u00e0:<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2094\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/aquarium-b4.png\" alt=\"aquarium-b4\" width=\"448\" height=\"444\" \/><br \/>\n&nbsp;<\/p>\n<ul>\n<li><span style=\"color: #ff0000;\">\u00c0 la fin d&rsquo;une partie, afficher le total d&rsquo;oxyg\u00e8ne accumul\u00e9 dans la fen\u00eatre de fin de la partie.<\/span><strong style=\"color: #ff0000;\">\u00a0<\/strong><\/li>\n<li><span style=\"color: #ff0000;\">\u00c0 la fin d&rsquo;une partie, afficher le nombre\u00a0de secondes\u00a0sans perte de vie.<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Capturer et poster sur twitter, la fen\u00eatre de fin de partie. Note: Masquer la zone menu avant la capture.<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Cr\u00e9er le tableau des mod\u00e8les de poissons \u00e0 partir du fichier personnages.plist.\u00a0<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Modifier le constructeur de la classe Poisson pour y recevoir la vitesse et la direction du poisson.<\/span><\/li>\n<li><span style=\"color: #ff0000;\">\u00c9liminer la r\u00e9f\u00e9rence \u00e0 \u00ab\u00a0p12\u00a0\u00bb dans la classe poisson.<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Afficher un poisson mort &lsquo;invers\u00e9&rsquo; lorsque le poisson\u00a0se d\u00e9place vers la droite.<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Cr\u00e9er une classe bulles\u00a0\u00e0 partir des images du projet<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Placer deux colonnes de bulles \u00e0 l&rsquo;\u00e9cran.<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Au d\u00e9marrage de l&rsquo;app, ajouter un nombre al\u00e9atoire de plantes anim\u00e9es (entre 7 et 16) \u00e0 une position (x,y) al\u00e9atoire (taille de l&rsquo;\u00e9cran) dans la partie inf\u00e9rieure de la sc\u00e8ne.\u00a0<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Afficher (pendant 5 secondes), au d\u00e9marrage, \u00a0un \u00e9cran de pr\u00e9sentation de l&rsquo;application (voir le storyboard au d\u00e9but du document).<\/span><\/li>\n<\/ul>\n<p>Note: \u00a0Placer un poisson avant une plante: il est possible d&rsquo;ins\u00e9rer une View avant une autre:<\/p>\n<p style=\"color: #3d1d81;\"><span style=\"color: #703daa;\">view<\/span><span style=\"color: #000000;\">.<\/span>insertSubview<span style=\"color: #000000;\">(<\/span><span style=\"color: #3c828c;\">Poisson<\/span><span style=\"color: #000000;\">(<\/span><\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 nomPoisson: <span style=\"color: #c91b13;\">\u00ab\u00a0Poisson <\/span>\\(compteur++)<span style=\"color: #c91b13;\">\u00ab\u00a0<\/span>,<br \/>\nnomImage: poissonCourant.<span style=\"color: #539aa4;\">nom<\/span>,<br \/>\nnbImages: poissonCourant.<span style=\"color: #539aa4;\">nbImagesAnimation<\/span>,<br \/>\nposX: _positionX <span style=\"color: #3d1d81;\">*<\/span> poissonCourant.<span style=\"color: #539aa4;\">directionDeplacement<\/span>,<br \/>\nposY: _positionY,<br \/>\nlargeur: _largeur,<br \/>\nhauteur: _hauteur,<br \/>\nvitesseDeplacement:_vitesse,<br \/>\ndirectionDeplacement:poissonCourant.<span style=\"color: #539aa4;\">directionDeplacement<\/span> ,<br \/>\nleDelegate: <span style=\"color: #c32275;\">self<\/span>),<br \/>\n<strong>belowSubview<\/strong>: planteAuHasard)<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2158\" src=\"\/xcode\/wp-content\/uploads\/2014\/10\/mort-droite.png\" alt=\"mort-droite\" width=\"144\" height=\"144\" \/><br \/>\n&nbsp;<br \/>\nFIN du document<\/p>\n<hr \/>\n<h6 style=\"text-align: right;\">Document pr\u00e9par\u00e9 par Alain Boudreault (c) 2014-2015<\/h6>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Contenu &nbsp; Construction d&rsquo;une classe Swift Propri\u00e9t\u00e9s M\u00e9thodes Constructeur: init(Param1, Param2, Param3) Constructeur de convenance: init(param1) Destructeur: deinit Construction d&rsquo;une classe avec interface visuelle (super classe:UIImageView) Animer une s\u00e9rie d&rsquo;images Programmation d&rsquo;un NSTimer D\u00e9finition d&rsquo;un protocole personnalis\u00e9 Gestion du protocole Gestion de l&rsquo;\u00e9cran tactile: touchesBegan &nbsp; &nbsp; &nbsp; \u00a0Note de mise \u00e0 jour de Xcode [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1998","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages\/1998","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/comments?post=1998"}],"version-history":[{"count":0,"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/pages\/1998\/revisions"}],"wp:attachment":[{"href":"https:\/\/ve2cuy.com\/xcode\/wp-json\/wp\/v2\/media?parent=1998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}