<file_sep>//
//  ViewController.swift
//  Touch ID
//
//  Created by <NAME> on 28/02/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit
import LocalAuthentication


class ViewController: UIViewController {

    @IBOutlet weak var infoLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        if #available(iOS 9.0, *) {
            //A partir de iOS 9
            
            let authenticationContext = LAContext()
            var error: NSError?
            
            if authenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
                authenticationContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Posez votre doigt sur le capteur d'empreinte pour dévérouiller votre application", reply: { (success: Bool, error: Error?) in
                    
                    if success {
                        //Empreinte OK
                        self.performSegue(withIdentifier: "mdp_ok", sender: self)
                    } else {
                        //L'utilisateur à annulé ou choisi de rentrer un mot de passe à la place
                        if let evaluateError = error as? NSError {
                            let code_erreur:Int = evaluateError.code
                            let msg_erreur:String = self.getInfoAvecCode(code: code_erreur)
                            
                            self.infoLabel.text = msg_erreur
                            
                            if( code_erreur == LAError.userFallback.rawValue ){
                                //L'utilisateur préfère rentrer son mot de passe
                                self.demanderMotDePasse()
                            }
                        }
                    }
                    
                })
            } else {
                //Si il n'y a pas pas de lecteur d'empreinte digitale
                demanderMotDePasse()
            }
        } else {
            //Si on est dans iOS inférieur à la version 9.0
            demanderMotDePasse()
        }
        
        
    }
    
    func demanderMotDePasse() {
        infoLabel.text = "Entrez votre mot de passe"
        //Faire quelque chose pour demander le mot de passe à la place
        //Ce doit être votre propre systeme..
        //...
    }
    
    //Optionel, juste pour mettre des message personalisés, traduisez-les :)
    func getInfoAvecCode(code: Int) -> String {
        var message = ""
        
        /*
         Si code = -9, afficher "Authentication was cancelled by application"
         Si code = -1, afficher "The user failed to provide valid credentials"
         ...etc
         */
        
        switch code {
        case LAError.appCancel.rawValue://-9
            message = "Authentication was cancelled by application"
            
        case LAError.authenticationFailed.rawValue://-1
            message = "The user failed to provide valid credentials"
            
        case LAError.invalidContext.rawValue://-10
            message = "The context is invalid"
            
        case LAError.passcodeNotSet.rawValue://..etc
            message = "Passcode is not set on the device"
            
        case LAError.systemCancel.rawValue:
            message = "Authentication was cancelled by the system"
            
        case LAError.touchIDLockout.rawValue:
            message = "Too many failed attempts."
            
        case LAError.touchIDNotAvailable.rawValue:
            message = "TouchID is not available on the device"
            
        case LAError.userCancel.rawValue:
            message = "The user did cancel"
            
        case LAError.userFallback.rawValue:
            //message = "The user chose to use the fallback"
            message = "Entrez le mot de passe"
            
        default:
            message = "Did not find error code on LAError object"
        }
        
        return message
    }

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


}

<file_sep>//
//  ViewController.swift
//  Touch ID
//
//  Created by <NAME> on 28/02/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit
import LocalAuthentication


class ViewController: UIViewController {

    @IBOutlet weak var infoLabel: UILabel!
    @IBOutlet weak var motDePasse: UITextField!
    var motDePasseTest:String = "12341234"
    
    /* NSUserDefaults est capable de stoquer:
     NSData, NSString, NSNumber, NSDate, NSArray, ou NSDictionary.
     https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html
     */
    let maVariableIneffacable:UserDefaults = UserDefaults.standard
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let deverouillerParTouchID:Bool = maVariableIneffacable.bool(forKey: "deverouillerParTouchID") as Bool
        if(deverouillerParTouchID) {
            verifParEmpreinteDigitale()
        }
        //Sinon, l'authentification par mot de passe est proposé dans tous les cas
        
    }
    
    func verifParEmpreinteDigitale() {
        if #available(iOS 9.0, *) {
            //A partir de iOS 9
            
            let myContext = LAContext()
            let myLocalizedReasonString = "Posez votre doigt sur le capteur d'empreinte pour dévérouiller votre application"
            
            var authError: NSError? = nil
            if myContext.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
                myContext.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedReasonString) { (success, evaluateError) in
                    if (success) {
                        //Empreinte OK
                        self.performSegue(withIdentifier: "mdp_ok", sender: self)
                    } else {
                        //L'utilisateur à annulé ou choisi de rentrer un mot de passe à la place
                        if let evaluateError = evaluateError as? NSError {
                            let code_erreur:Int = evaluateError.code
                            let msg_erreur:String = Fonctions.getInfoAvecCode(code: code_erreur)
                            
                            self.infoLabel.text = msg_erreur
                        }
                    }
                }
            }
        }
    }
    
    @IBAction func verifParMDP(_ sender: UIButton) {
        if( motDePasse.text == motDePasseTest ){
            self.performSegue(withIdentifier: "mdp_ok", sender: self)
        } else {
            infoLabel.text = "Mot de passe incorect"
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

<file_sep>//
//  ParametreViewController.swift
//  Touch ID
//
//  Created by <NAME> on 28/02/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit
import LocalAuthentication

class ParametreViewController: UIViewController {
    
    @IBOutlet weak var touchIdSwitch: UISwitch!
    let maVariableIneffacable:UserDefaults = UserDefaults.standard
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        touchIdSwitch.addTarget(self, action: #selector(evenementSwitch(leSwitch:)), for: UIControlEvents.valueChanged)
        
        let deverouillerParTouchID:Bool = maVariableIneffacable.bool(forKey: "deverouillerParTouchID") as Bool
        if(deverouillerParTouchID) {
            //Metre à ON quand l'utilisateur à déjà validé son empreinte et revient sur l'application
            touchIdSwitch.setOn(true, animated: true)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func evenementSwitch(leSwitch: UISwitch) {
        if leSwitch.isOn {
            verifEmpreinteDigitale()
        } else {
            self.maVariableIneffacable.set(false, forKey: "deverouillerParTouchID")
        }
    }
    
    func verifEmpreinteDigitale() {
        if #available(iOS 9.0, *) {
            //A partir de iOS 9
            
            let myContext = LAContext()
            let myLocalizedReasonString = "Posez votre doigt sur le capteur d'empreinte pour confirmé"
            
            var authError: NSError? = nil
            if myContext.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
                myContext.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedReasonString) { (success, evaluateError) in
                    if (success) {
                        //Empreinte OK
                        self.maVariableIneffacable.set(true, forKey: "deverouillerParTouchID")
                    } else {
                        //L'utilisateur a annulé
                        self.touchIdSwitch.setOn(false, animated: true)//Metre à OFF
                        self.alert("Impossible", "Impossible d'effectuer l'action")
                    }
                    
                }
            } else {
                alert("Introuvable", "Vous n'avez pas de lecteur d'empreinte digitale")
                touchIdSwitch.setOn(false, animated: true)//Metre à OFF
            }
        } else {
            alert("Introuvable", "Vous n'avez pas de lecteur d'empreinte digitale")
            touchIdSwitch.setOn(false, animated: true)//Metre à OFF
        }
    }
    
    func alert(_ titre: String, _ message: String) {
        let alert = UIAlertController(title: titre, message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default)
        
        alert.addAction(okAction)
        
        present(alert, animated: true)
    }
    
}
<file_sep>//
//  PrevisonsViewController.swift
//  Meteo
//
//  Created by <NAME> on 13/05/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit

class PrevisonsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var ville:String = ""
    @IBOutlet weak var barre_haut: UINavigationBar!
    @IBOutlet weak var tableView: UITableView!
    var data = [Meteo]()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        barre_haut.topItem?.title = "Prévisons de \(ville)"
        
        do {
            let url = NSURL(string: "http://api.openweathermap.org/data/2.5/forecast?appid=79ab92ee7aba089ef7c6dbb6c96c9a54&units=metric&q=\(ville)");
            let texte:NSString = try NSString(contentsOf: url! as URL, usedEncoding: nil)
            
            let jsonData = texte.data(using: 4)
            let jsonResult: NSDictionary? = try JSONSerialization.jsonObject(with: jsonData!) as? NSDictionary
            
            if let jsonResult = jsonResult {
                let list = jsonResult["list"]! as! NSArray
                
                for meteo_ in list {
                    let meteo:NSDictionary = meteo_ as! NSDictionary
                    let dt = meteo["dt"]! as! Int
                    let main = meteo["main"]! as! NSDictionary
                    let weather_array = meteo["weather"]! as! NSArray
                    let weather = weather_array[0] as! NSDictionary
                    
                    let id_condition:Int = weather["id"] as! Int
                    let temp = main["temp"] as! Double
                    
                    self.data.append(Meteo(unix: dt, temp: temp, id_condition: id_condition))
                }
                
            }
        } catch {
            print("Erreur de conversion")
        }
    }

    @IBAction func quitter(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
    }
    
    
    
    // MARK: - Table View
    
    func numberOfSections(in tableView: UITableView) -> Int
    {
        //Nombre de section: Une seule
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        //Nombre de cellules à afficher:
        return self.data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        //Customisation de notre cellule
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cellule") as! CustomTableViewCell
        
        let meteo:Meteo = self.data[indexPath.row]
        
        cell.icone.image = UIImage(named: meteo.nom_image)
        cell.degre.text = "\(meteo.temperature) °C"
        cell.description_meteo.text = meteo.description
        cell.date.text = meteo.date_string
        
        return cell
    }
}
<file_sep>//
//  CustomTableViewCell.swift
//  Meteo
//
//  Created by <NAME> on 13/05/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit

class CustomTableViewCell: UITableViewCell {

    @IBOutlet weak var icone: UIImageView!
    @IBOutlet weak var degre: UILabel!
    @IBOutlet weak var description_meteo: UILabel!
    @IBOutlet weak var date: UILabel!
    
}
<file_sep>//
//  Meteo.swift
//  Meteo
//
//  Created by <NAME> on 13/05/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation

class Meteo {
    
    var date_string:String = ""
    var temperature:Double = 0.0
    var description:String = ""
    var nom_image:String = ""
    
    init(unix:Int, temp:Double, id_condition:Int) {
        traiter_date(unix: unix)
        traiter_conditions(id: id_condition)
        self.temperature = temp
    }
    
    private func traiter_date(unix:Int) {
        let ns_date = NSDate(timeIntervalSince1970: TimeInterval(unix))
        let date:Date = ns_date as Date
        
        let date_formatter:DateFormatter = DateFormatter()
        date_formatter.dateFormat = "dd MMM YYYY à HH:mm" //03 Mai 2017 à 09:00
        self.date_string = date_formatter.string(from: date)+"H"
    }
    
    private func traiter_conditions(id:Int) {
        switch id {
        case 200...232:
            self.nom_image = "11d.png"
            self.description = "Orage"
        case 300...321, 520...531:
            self.nom_image = "09d.png"
            self.description = "Pluie nuageuse"
        case 500...504:
            self.nom_image = "10d.png"
            self.description = "Pluie ensoleillé"
        case 511:
            self.nom_image = "13d.png"
            self.description = "Pluie verglaçante"
        case 800:
            self.nom_image = "01d.png"
            self.description = "Ciel clair"
        case 801...804:
            self.nom_image = "03d.png"
            self.description = "Nuageux"
        default:
            self.nom_image = "01d.png"
            self.description = "Ciel clair"
        }
    }
}
<file_sep>//
//  ViewController.swift
//  Meteo
//
//  Created by <NAME> on 13/05/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var image_fond: UIImageView!
    @IBOutlet weak var degre: UILabel!
    @IBOutlet weak var icone: UIImageView!
    @IBOutlet weak var description_meteo: UILabel!
    @IBOutlet weak var ville: UITextField!
    @IBOutlet weak var date: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        rechercher(ville: "Paris")
    }
    
    func rechercher(ville:String) {
        do {
            let url = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?appid=79ab92ee7aba089ef7c6dbb6c96c9a54&units=metric&q=\(ville)");
            let texte:NSString = try NSString(contentsOf: url! as URL, usedEncoding: nil)
            
            let jsonData = texte.data(using: 4)
            let jsonResult: NSDictionary? = try JSONSerialization.jsonObject(with: jsonData!) as? NSDictionary
            
            if let jsonResult = jsonResult {
                let weather_array = jsonResult["weather"] as! NSArray
                let weather = weather_array[0] as! NSDictionary
                let main = jsonResult["main"] as! NSDictionary
                let dt = jsonResult["dt"]! as! Int
                
                let id_condition:Int = weather["id"] as! Int
                let temp = main["temp"] as! Double
                
                let meteo:Meteo = Meteo(unix: dt, temp: temp, id_condition: id_condition)
                afficher(m: meteo)
            }
        } catch {
            print("Erreur de conversion")
        }
    }

    func afficher(m:Meteo) {
        icone.image = UIImage(named: m.nom_image)
        image_fond.image = UIImage(named: "f-"+m.nom_image)
        degre.text = "\(m.temperature) °C"
        description_meteo.text = m.description
        date.text = "Dernière mise à jour le \(m.date_string)"
    }
    
    @IBAction func rechercher(_ sender: UIButton) {
        rechercher(ville: ville.text!)
    }
    
    
    //MARK - Navigation
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if(segue.identifier=="aller_vers_previsons"){
            let previsonsVC:PrevisonsViewController = segue.destination as! PrevisonsViewController
            previsonsVC.ville = ville.text!
        }
    }


}

