NumberFormatter monnaie €

easydeasyd Membre

Bonjour tous le monde,


 


Je rencontre un petit problème pour le format monnaie que je veux utiliser :



ui_pric = (person["price"] as? String)!
print("fffff",ui_pric)

let number = NSDecimalNumber(decimal: 10000000)

let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.maximumFractionDigits = 0
formatter.locale = Locale(identifier: "fr_FR")
let nombre = formatter.string(from: number)

print(nombre!)

Ce que je voudrai faire :



ui_pric = (person["price"] as? String)!
print("fffff",ui_pric)

let number = NSDecimalNumber(decimal: ui_pric )

let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.maximumFractionDigits = 0
formatter.locale = Locale(identifier: "fr_FR")
let nombre = formatter.string(from: number)

print(nombre!)

Cela ne fait un erreur.


 


Merci de votre aide,


 


«1

Réponses

  • LarmeLarme Membre

    Quelle erreur ?


    Mon avis ? Tu dis que ui_pric est un "String", dans le cas qui fonctionne, tu passes un nombre en paramètre, mais pas dans le cas qui ne fonctionne pas. Regarde si tu as une alternative, ou alors convertit String en Int (ou Float)


  • DrakenDraken Membre
    mai 2017 modifié #3

    ui_pric = (person["price"] as? String)!

    Beurk .. Tu lis un dictionnaire en convertissant le résultat en un String?, forcé immédiatement après en String. Si "price" n'existe pas dans le dictionnaire, c'est le plantage assuré.


     


    Tu as encore des problèmes avec l'utilisation des optionals. L'opérateur ! c'est le MAL ..  >:D


     


    Une variante qui fonctionne :


    a



    // Dico bidon pour le test
    let person:[String:String] = ["price":"7645687"]

    if let prix = person["price"] {
    let number = NSDecimalNumber(string: prix)
    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = 0
    formatter.locale = Locale(identifier: "fr_FR")
    if let nombre = formatter.string(from: number) {
    print(nombre)
    }
    }

    "   "



    let number = NSDecimalNumber(decimal: ui_pric )

    a


    Ton problème venait du fait qu'une String n'est pas un Decimal. NSDecimalNumber a plusieurs variantes, selon la donnée à  convertir. Toi tu as besoin de :


    a



    let number = NSDecimalNumber(string: prix)

    a


    L'auto-complétion d'Xcode permet de connaà®tre les variantes d'une fonction, sans fouiller dans la documentation :


     


     


     


  • easydeasyd Membre
    mai 2017 modifié #4

    Merci beaucoup ça fonctionne



    ...
        var ui_pric = String()
    ...

    ui_pric1 = (person["price"] as? String)!
    print("fffff",ui_pric)

    let number = NSDecimalNumber(string: ui_pric)

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = 0
    formatter.locale = Locale(identifier: "fr_FR")
    let nombre = formatter.string(from: number)

    print(nombre!)

  • Joanna CarterJoanna Carter Membre, Modérateur
    Quoi !!!


    Tu continues à  utiliser les !!!!!!!!!!!!!


    Surtout avec les lignes comme :

    ui_pric1 = (person["price"] as? String)!

    Qu'est-ce qu'il arrive si le clé n'existe pas ?


    Qu'est-ce qu'il arrive si la conversion vers String s'échouait ?


    Il faut utiliser le guard comme :


    guard let priceValue = person["price"], // le clé est bon
    let ui_pric1 = priceValue as? String else // le valeur est bien un String
    {
    return // erreur !!!
    }

    Mais, je te demanderais, pourquoi stocker les valeurs numériques comme string ?


    Et pourquoi récupérer un valeur en string pour le passer à  un NumberFormatter pour le mettre en string ?
  • DrakenDraken Membre


    Mais, je te demanderais, pourquoi stocker les valeurs numériques comme string ?



    Et pourquoi récupérer un valeur en string pour le passer à  un NumberFormatter pour le mettre en string ?


     




     


    J'ai pensé la même chose, puis je me suis dit qu'il n'est peut-être pas responsable du format du dictionnaire. Que c'est probablement un flux de donnés venant d'un serveur.

  • easydeasyd Membre

    OUi c'est cela je récupérer l'information d'un serveur.


     


    Merci a vous,


  • easydeasyd Membre
    mai 2017 modifié #8

    J'ai un petit problème, j'essaye de faire une condition mais ça donne rien :



    ...
    var ui_pric = String()
    ...

    ui_pric1 = (person["price"] as? String)!
    print("fffff",ui_pric)

    let number = NSDecimalNumber(string: ui_pric)

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = 0
    formatter.locale = Locale(identifier: "fr_FR")
    let nombre = formatter.string(from: number)

    print(nombre!)

    let pasprix = "pas de prix"

    if nombre != 0 {
    pr.text = nombre
    }else{
    pasprix
    }
    ....

    Merci a vous,


  • DrakenDraken Membre
    mai 2017 modifié #9

    Tu as juste besoin de tester si "price" existe dans le dictionnaire



    if let prix = person["price"] as? String {
    // Ici le prix existe
    // ...
    } else {
    // Ici le prix n'existe pas "
    print ("PAS DE PRIX !")
    }


  • Joanna CarterJoanna Carter Membre, Modérateur

    Mon cher easyd - pourquoi tu continues à  ignorer nos conseils ? Pourquoi tu continues à  répéter le même code avec ls même fautes ?


     




    OUi c'est cela je récupérer l'information d'un serveur.




     


    Et su connais, totalement sans doute, le format des données ? Il ne soit pas possible que quelqu'un puisse faire une erreur en les saisissant ?


     


     


    En plus de ce que Draken a dit :



    ...
    var ui_pric = String()
    ...

    ui_pric1 = (person["price"] as? String)!

    Pourquoi tu initialises ui_pric1 avant de le modifier ? Et, si tu ne prévois changer la valeur, tu devrais utiliser un let.


     


    Il suffirait de faire :



    let ui_pric1 = (person["price"] as? String)!

    Mais, comme nous avons déjà  discuté, cette ligne est vraiment dangereux.


     


    Il faut - sans question - sans argument - faire les tests à  chaque étape.


     


    Il y a, au moins, trois options probables pour la valeur que aurait pû être stocké dans le dictionnaire :



    ["price" : "123"]


    ["price" : 123]


    ["price" : 123.0]

    Avec le code test :



    if let priceValue = person["price"]
    {
    // c'est bon tu as une valeur pour le clé.

    if let priceAsString = priceValue as? String // premier exemple
    {
    // c'est à  dire que la valeur en priceValue est bien un String

    pr.text = priceAsString // on n'a pas besoin de faire l'aller-retour avec NSDecimalNumber
    }

    if let priceAsNumber = priceValue as? NSNumber // deuxième exemple
    {
    // c'est à  dire que la valeur en priceValue est bien un NSNumber

    let formatter = NumberFormatter()

    formatter.numberStyle = .currency

    formatter.maximumFractionDigits = 0

    formatter.locale = Locale.autoupdatingCurrent // si l'utilisateur préfère d'utiliser une autre région que la France

    if let priceText = formatter.string(from: priceAsNumber) // car le résultat du formatter pourrait être nil
    {
    pr.text = priceText
    }
    }

    if let priceAsDouble = priceValue as? Double // troisième exemple
    {
    // c'est à  dire que la valeur en priceValue est bien un Double

    let formatter = NumberFormatter()

    formatter.numberStyle = .currency

    formatter.maximumFractionDigits = 0

    formatter.locale = Locale.autoupdatingCurrent // si l'utilisateur préfère d'utiliser une autre région que la France

    if let priceText = formatter.string(for: priceAsDouble) // car le résultat du formatter pourrait être nil
    {
    pr.text = priceText
    }
    }
    }
    else
    {
    // on n'a pas un prix

    pr.text = "pas de prix"

    print(pr.text)
    }

    Su tu ne fais pas ces tests, ton appli va exploser sans explication pour l'utilisateur  >:(


     


    On peut, bien sûr, simplifier ce code mais je l'ai écrit comm ça pout te montrer clairement le minimum de tests qu'il fasse faire.

  • easydeasyd Membre
    mai 2017 modifié #11

    Bonjour tous le monde,


     


    Merci pour ton aide.


    Je vient de faire le changement avec le 2 choix, mais cela ne me donne rien pas de résultat.


    quant il y a pas de prix c'est un zéro.


     


    Voilà  mon code :



    import UIKit
    import CoreLocation
    import SceneKit
    import AlamofireImage
    import Alamofire
    import ImageSlideShowSwift

    class DetailForRentTableViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var titre: UILabel!
    @IBOutlet weak var ui_details: UILabel!
    @IBOutlet weak var ui_price: UILabel!
    @IBOutlet weak var ui_nref: UILabel!
    @IBOutlet weak var ui_titre: UILabel!
    @IBOutlet weak var img0:UIImageView!

    fileprivate var images:[Image] = []


    // var ui_pric1 = String()
    var ui_pric = String()

    var ui_ps = String()
    var ui_pt = String()
    var ui_rs = String()
    var ui_cs = String()
    var ui_ta = String()
    var ui_nbp = String()
    var ui_cy = String()
    var ui_dt = String()
    var ui_bg = String()
    var TabInfos = String()
    var Ui_nre = String()
    var emailLabel = String()
    var txtId_produit = String()
    var txtType_produit = String()
    var TabInfos1 = String()


    // @IBOutlet weak var images: UIImageView!

    var persons:[String:AnyObject]?

    override func viewDidLoad() {
    super.viewDidLoad()

    if NetworkViewController.isConnectedToNetwork() == true
    {

    }
    else
    {
    print("Internet connection FAILED")

    let title = NSLocalizedString("No Internet Connection", comment: "TITLE")
    let msg = NSLocalizedString("Make sure your device is connected to the internet.", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)
    }

    self.generateImages()


    /* if revealViewController() != nil {
    //revealViewController().rearViewRevealWidth = 62
    menuButton.target = revealViewController()
    menuButton.action = #selector(SWRevealViewController.revealToggle(_:))

    revealViewController().rightViewRevealWidth = 220
    extraButton.target = revealViewController()
    extraButton.action = #selector(SWRevealViewController.rightRevealToggle(_:))
    view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
    }
    */

    if !(self.persons?["img0"] is NSNull){
    Alamofire.request(self.persons?["img0"] as! String)
    .responseImage { response in

    if let image1 = response.result.value {
    self.img0.image = image1
    }
    }
    }

    }

    override func viewWillAppear(_ animated: Bool) {

    if let person = persons {

    // ui_pric1 = (person["price"] as? String)!
    // print("fffff",ui_pric)

    // let number = NSDecimalNumber(string: ui_pric1)
    //
    // let formatter = NumberFormatter()
    // formatter.numberStyle = .currency
    // formatter.maximumFractionDigits = 0
    // formatter.locale = Locale(identifier: "fr_FR")
    // let nombre = formatter.string(from: number)
    //
    // print(nombre!)
    //
    // ui_price.text = nombre!
    // ui_pric = nombre!


    ui_titre.text = person["titre_extraction_jr"] as? String
    ui_details.text = person["description_extraction_jr"] as? String
    ui_nref.text = person["ref"] as? String

    ui_cs = (person["cellars"] as? String)!
    ui_ps = (person["bedrooms"] as? String)!
    ui_ta = (person["total_area"] as? String)!
    ui_cy = (person["country"] as? String)!
    ui_dt = (person["district"] as? String)!
    ui_bg = (person["building"] as? String)!
    ui_pt = (person["product_type"] as? String)!
    ui_nbp = (person["nb_parkings"] as? String)!
    ui_rs = (person["rooms"] as? String)!

    TabInfos1 = (person["ref"] as? String)!

    print("TabInfos1", TabInfos1)

    if let priceValue = person["price"]
    {

    if let priceAsNumber = priceValue as? NSNumber // deuxième exemple
    {
    // c'est à  dire que la valeur en priceValue est bien un NSNumber

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = 0

    formatter.locale = Locale.autoupdatingCurrent // si l'utilisateur préfère d'utiliser une autre région que la France

    if let priceText = formatter.string(from: priceAsNumber) // car le résultat du formatter pourrait être nil
    {
    ui_price.text = priceText
    }
    }
    }else{

    ui_price.text = "pas de prix"
    ui_pric = "pas de prix"


    print(ui_price.text!)
    }

    }
    }

    class Image:NSObject, ImageSlideShowProtocol {
    fileprivate let url:URL

    init(url:URL) {
    self.url = url
    }

    func slideIdentifier() -> String {
    return String(describing: url)
    }

    func image(completion: @escaping (_ image: UIImage?, _ error: Error?) -> Void) {

    let session = URLSession(configuration: URLSessionConfiguration.default)
    session.dataTask(with: self.url) { data, response, error in

    if let data = data, error == nil
    {
    let image = UIImage(data: data)
    completion(image, nil)
    }
    else
    {
    completion(nil, error)
    }

    }.resume()

    }
    }


    fileprivate func generateImages()
    {
    images = [

    Image(url: URL(string: self.persons?["img0"] as! String)!),
    Image(url: URL(string: self.persons?["img1"] as! String)!),
    Image(url: URL(string: self.persons?["img2"] as! String)!),
    Image(url: URL(string: self.persons?["img3"] as! String)!),
    Image(url: URL(string: self.persons?["img4"] as! String)!),
    Image(url: URL(string: self.persons?["img5"] as! String)!),
    Image(url: URL(string: self.persons?["img6"] as! String)!),
    Image(url: URL(string: self.persons?["img7"] as! String)!),
    Image(url: URL(string: self.persons?["img8"] as! String)!),
    Image(url: URL(string: self.persons?["img9"] as! String)!),
    Image(url: URL(string: self.persons?["img10"] as! String)!)
    ]
    }

    @IBAction func presentSlideShow(_ sender:AnyObject?)
    {
    ImageSlideShowViewController.presentFrom(self){ [weak self] controller in

    controller.dismissOnPanGesture = true
    controller.slides = self?.images
    controller.enableZoom = true
    controller.controllerDidDismiss = {
    debugPrint("Controller Dismissed")
    }
    }
    }

    @IBAction func favories(_ sender : UIButton) {


    let prefs:UserDefaults = UserDefaults.standard
    let isLoggedIn:Int = prefs.integer(forKey: "ISLOGGEDIN") as Int
    if (isLoggedIn != 1) {
    self.performSegue(withIdentifier: "goto_login", sender: self)
    } else {

    let Ui_nre:String = ui_nref.text! as String
    let Type_produit:String = txtType_produit as String
    let emailLabel = (prefs.value(forKey: "EMAIL") as? String)!

    if ( emailLabel.isEqual("") || Type_produit.isEqual("") || Ui_nre.isEqual("")) {

    let alertView:UIAlertController = UIAlertController()
    alertView.title = "Sign in Failed!"
    alertView.message = "Please enter Username and Password"

    do {
    let post:String = "user_emails=\(emailLabel)&ref_produit=\(Ui_nre)&type_produit=\(3)" as String

    NSLog("PostData: %@",post);

    let url:URL = URL(string:"http://lien_serveur/myfavorie_user.php")!
    let postData:Data = post.data(using: String.Encoding(rawValue: String.Encoding.ascii.rawValue))!
    let postLength:String = String( postData.count ) as String
    var request:URLRequest = NSMutableURLRequest(url: url) as URLRequest

    request.httpMethod = "POST"
    request.httpBody = postData
    request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")

    var reponseError: Error?
    var response: URLResponse?
    var urlData: Data?

    do {
    urlData = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response)
    } catch let error as Error {
    reponseError = error
    urlData = nil
    }

    if ( urlData != nil ) {
    let res = response as! HTTPURLResponse!;

    if ((res?.statusCode)! >= 200 && (res?.statusCode)! < 300)
    {
    let responseData:String = String(data:urlData!, encoding:String.Encoding(rawValue: String.Encoding.utf8.rawValue))!

    NSLog("Response ==> %@", responseData);

    let jsonData:NSDictionary = try JSONSerialization.jsonObject(with: urlData!, options:JSONSerialization.ReadingOptions.mutableContainers ) as! NSDictionary

    let success:NSInteger = jsonData.value(forKey: "success") as! NSInteger

    NSLog("Success: %ld", success);

    if(success == 1)
    {

    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)

    //self.dismiss(animated: true, completion: nil)
    } else {
    var error_msg:String

    if jsonData["error_message"] as? String != nil {
    error_msg = jsonData["error_message"] as! String
    } else {
    error_msg = "Unknown Error"
    }

    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)

    }

    } else {

    let title = NSLocalizedString("Error", comment: "TITLE")
    let msg = NSLocalizedString("Account already exists", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)

    }
    } else {
    let alertView:UIAlertController = UIAlertController()
    alertView.title = "Sign in Failed!"
    alertView.message = "Connection Failure"
    if let error = reponseError {
    alertView.message = (error.localizedDescription)
    }

    }
    } catch {
    let title = NSLocalizedString("Error", comment: "TITLE")
    let msg = NSLocalizedString("Account already exists", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)
    self.present(alert, animated: true, completion: nil)


    }
    }

    }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
    if segue.identifier == "showDetail",
    let personViewController = segue.destination as? interestsmeViewController
    {
    personViewController.tabInfos = TabInfos1
    print("TabInfosddd", personViewController.tabInfos)
    }

    }

    @IBAction func alertController(sender: AnyObject) {

    let alertController = UIAlertController(title: "Dà‰TAILS", message: "", preferredStyle: .alert)

    let buttonZero = UIAlertAction(title: "Prix : \(ui_pric)", style: .default, handler: { (action) -> Void in
    print("Button One Pressed")

    })

    let buttonOne = UIAlertAction(title: "Type de produit : \(ui_pt)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })

    let buttonTwo = UIAlertAction(title: "Nb. pièces : \(ui_rs)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })

    let buttonThree = UIAlertAction(title: "Nb. Chambres : \(ui_ps)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })

    let buttonFour = UIAlertAction(title: "Caves : \(ui_nbp)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })

    let buttonFours = UIAlertAction(title: "Garages : \(ui_cs)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })


    let buttonFive = UIAlertAction(title: "Surface Totale m² : \(ui_ta)", style: .default, handler: { (action) -> Void in
    print("Button Two Pressed")
    })

    let buttonSix = UIAlertAction(title: "Immeuble : \(ui_bg)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })
    let buttonSeven = UIAlertAction(title: "Quartier : \(ui_dt)", style: .default, handler: { (action) -> Void in
    print("Button Four Pressed")
    })

    let buttonEight = UIAlertAction(title: "Ville : \(ui_cy)", style: .default, handler: { (action) -> Void in
    print("Button Three Pressed")
    })


    let buttonCancel = UIAlertAction(title: "", style: .cancel) { (action) -> Void in
    print("Cancel Button Pressed")

    }
    alertController.addAction(buttonZero)
    alertController.addAction(buttonOne)
    alertController.addAction(buttonTwo)
    alertController.addAction(buttonThree)
    alertController.addAction(buttonFour)
    alertController.addAction(buttonFours)
    alertController.addAction(buttonFive)
    alertController.addAction(buttonSix)
    alertController.addAction(buttonSeven)
    alertController.addAction(buttonEight)
    alertController.addAction(buttonCancel)
    present(alertController, animated: true, completion: nil)

    }
    }

    Merci de votre aide,


  • Joanna CarterJoanna Carter Membre, Modérateur
    mai 2017 modifié #12

    Donc, tu as un problème - peut-être le même problème d'extraction des valeurs d'un dictionnaire ?


     


    À part du fait que tu continues à  utiliser les lignes comme :



    ui_cs = (person["cellars"] as? String)!

    ... tu postes plus code :


     


    1. qui est moche et plein d'erreurs.


     


    2. n'a rien à  voir avec ton problème.


     


    3. contient les noms des var qui ne sont pas descriptifs


     


    4. contient les vars qui ne sont jamais utilisés


     


    5. contient les erreurs de logique


     


    6. le code pour la requête est particulièrement mal écrit ; tu n'a pas utilisé le try .. catch correctement


     


    Et il y a plusieurs autres fautes, trop nombreux pour les lister.


     


    Si tu veux de l'aide avec tes problèmes, il faut demander plus précisément et prendre compte des conseils que nous t'avons déjà  donné.


     


    S'il te plaà®t arrêtes d'ignorer les conseils en présentant le code qui contient les problèmes dont tu as déjà  reçu les corrections.


     


    Si j'étais disposée de t'aider, il me mettrait beaucoup de temps de le faire ; tu veux que je t'envoie un devis avant ?  :-*


  • Joanna CarterJoanna Carter Membre, Modérateur

    Oh, et pour :



    if !(self.persons?["img0"] is NSNull){

    Tu comprends que NSNull n'est pas la même chose que nil ?


     


    Pour tester si la valeur dans le dictionnaire est valide, il faut qqch. comme :



    if let persons = persons,
    let imageAsObject = persons["img0"] // tester pour nil
    {
    if imageAsObject is NSNull // puis tester pout NSNull
    {
    Alamofire.request(imageAsObject as! String)

    ...
    }
    }

    Mais ce code doit échouer parce que person est un dictionnaire de [String : AnyObject] et, même avec le point d'exclamation de mort, le transformation vers String n'est jamais possible, parce que String est une struct, pas une classe et, du coup, ne peut pas être comparé avec NSNull.


     


    S'il est prévu de stocker les Strings dans un dictionnaire, il faut utiliser [String : Any].

  • easydeasyd Membre

    Bonjour,


     


    Je comprend ce que tu veux dire et te remercie pour ces suggestions.


    Je vais faire plus d'efforts a ce niveau là .


     


    Je comprend mais je suis confrontée a moi même, j'ai personne avec qui discuter des différente problématique que je rencontre.


     


    Voilà  pourquoi votre aide mais très importante, cela me permet d'avancer a petits pas.


    Votre forum et le seul a aider ce qui bloque, beaucoup d'autre ne font pas d'effort comme vous.


     


    Voilà  ce que j'avais a dire ce matin et encore merci a vous tous se de vos aides.

  • Joanna CarterJoanna Carter Membre, Modérateur
    mai 2017 modifié #15

    OK. Mais tu dois nous dire pourquoi tu continues à  utiliser les '!' partout.


     


    Est-ce que c'est parce que le compilateur le propose comme solution ?


     


    Si oui, tu dois comprendre que le compilateur essaie d'être obligeant mais, en fait, ces suggestions ne prennent pas compte des effets secondaires.


     


    Je crois que la plupart de tes problèmes commencent parce que tu n'as pas lu et compris les docs sur les APIs.


     


    Je commence avec l'acquisition des données JSON.


     


    Les seules types que l'on trouve dans un objet JSON sont : NSString, NSNumber, NSArray, NSDictionary ou NSNull. Du coup, tu devrais, tout d'abord, tester pour ces types.


     


    Mais avant tout ça, il faut acquérir l'objet correctement.


     


    Si j'ai bien compris, l'intention de :



    @IBAction func favories(_ sender : UIButton)
    {
    ...
    }

    ... est de vérifier si l'article existe déjà  ou non ?


     


    Si oui, tu as utilisé un API deprecated :



    NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response)

    et, en plus, tu as ignorer l'avertissement dans les docs :


     



     


    Important


    Because this call can potentially take several minutes to fail (particularly when using a cellular network in iOS), you should never call this function from the main thread of a GUI application.



     


    Du coup, le code que tu as écrit est bien mauvais, dangereux et puisse embêter l'utilisateur lorsque l'appli se bloque.


     


    Du code plus correcte serait :



    @IBAction func favories()
    {
    let request = URLRequest(url: URL(fileURLWithPath: ""))

    URLSession.shared.dataTask(with: request, completionHandler:
    {
    [unowned self] data, response, error in

    if let error = error
    {
    if let response = response
    {
    print(error, response)

    // handle and display error using response data

    return // rien d'autre à  faire
    }

    print(error)

    // handle and display error

    return // rien d'autre à  faire
    }

    if data != nil // bonne réponse, article trouvé
    {
    let title = NSLocalizedString("FAVORITE", comment: "TITLE")

    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))

    self.present(alert, animated: true, completion: nil)
    }
    }).resume()
    }

    Beaucoup plus facile.


  • easydeasyd Membre
    mai 2017 modifié #16

    Merci encore,


    Juste pour information sur mon code :


     


     


    1/ Dans cette partie je vérifie que l'utilisateur est logué. S'il n'ai pas loger je le redirige vers un storyboard pour ce loger ou s'inscrire puis quant il ce logé cela revient sur le storyboard du produit et il s'enregistre dans les favori.



    let prefs:UserDefaults = UserDefaults.standard
    let isLoggedIn:Int = prefs.integer(forKey: "ISLOGGEDIN") as Int
    if (isLoggedIn != 1) {

    self.performSegue(withIdentifier: "goto_login", sender: self)




    2/ S'il est il continue l'action et enregistre dans la favoris le produit qu'il regarde (avec les info email, ref. produit et type produit 2 ou 3).



    } else {

    let Ui_nre:String = ui_nref.text! as String
    let Type_produit:String = txtType_produit as String
    let emailLabel = (prefs.value(forKey: "EMAIL") as? String)!

    if ( emailLabel.isEqual("") || Type_produit.isEqual("") || Ui_nre.isEqual("")) {

    let alertView:UIAlertController = UIAlertController()
    alertView.title = "Sign in Failed!"
    alertView.message = "Please enter Username and Password"

    do {
    ...

    }


    Voilà  les réponses du serveur :


    1/ Enregistrement dans  la BDD :



    2017-05-09 15:53:29.753531+0200 serveur[2260:440555] PostData: user_emails=client@gmail.com&ref_produit=02163&type_produit=3
    2017-05-09 15:53:29.967944+0200 serveur[2260:440555] Response ==> {"success": 1}
    2017-05-09 15:53:29.968342+0200 serveur[2260:440555] Success: 1

    2/ Existe dans la BDD :



    2017-05-09 15:52:39.904010+0200 serveur[2260:440555] PostData: user_emails=client@gmail.com&ref_produit=02201&type_produit=3
    2017-05-09 15:52:40.479874+0200 serveur[2260:440555] Response ==> {"success": 0,"error_message":"Exist favorite"}
    2017-05-09 15:52:40.480516+0200 serveur[2260:440555] Success: 0

    Voilà , merci de ton aide,


  • Joanna CarterJoanna Carter Membre, Modérateur

    Après que tu as vérifié que les corrections que je t'ai donné marchent ou non, nous pouvons aller plus loin. Du coup, j'ignore ton dernier message jusqu'à  là .


  • easydeasyd Membre

    OK , Juste une question


     


    handle and display error using response data ???


    handle and display error ??


     


    J'ai déjà 



    @IBAction func favories() {

    let request = URLRequest(url: URL(fileURLWithPath: "http://lien_serveur/myfavorie_user.php"))

    URLSession.shared.dataTask(with: request, completionHandler:
    {
    [unowned self] data, response, error in

    if let error = error
    {
    if let response = response
    {
    print(error, response)

    // handle and display error using response data

    return // rien d'autre à  faire
    }

    print(error)

    // handle and display error

    return // rien d'autre à  faire
    }

    if data != nil // bonne réponse, article trouvé
    {
    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment: "Please_enter_all_fields")
    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)
    }
    }).resume()
    }

    fait cela  :



    2017-05-09 16:42:29.885905+0200 serveur[2298:452597] -[serveur.DetailForRentTableViewController favories:]: unrecognized selector sent to instance 0x1018c4200
    2017-05-09 16:42:29.887018+0200 serveur[2298:452597] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[serveur.DetailForRentTableViewController favories:]: unrecognized selector sent to instance 0x1018c4200'
    *** First throw call stack:
    (0x185bfafd8 0x18465c538 0x185c01ef4 0x185bfef4c 0x185afad2c 0x18bd5f0ec 0x18bd5f06c 0x18bd495e0 0x18bd5e950 0x18c2f346c 0x18c2ef7b8 0x185ba89a0 0x185ba6628 0x185ba6a74 0x185ad6d94 0x187540074 0x18bd8f130 0x100078250 0x184ae559c)
    libc++abi.dylib: terminating with uncaught exception of type NSException


    Voilà ,

  • Joanna CarterJoanna Carter Membre, Modérateur
    mai 2017 modifié #19

    Traduction - gérer et afficher l'erreur (en utilisant response)


     


    Et l'erreur de "unrecognised selector ..." c'est parce que tu as copié/collé mon code sans le vérifiant. Regardes ton ancien code ; la méthode à  un paramètre qui manque la mienne.


  • easydeasyd Membre

    Bonjour,


     


    Voilà  ce que j'ai fait



    @IBAction func favories() {

    let request = URLRequest(url: URL(fileURLWithPath: "http://lien_serveur/myfavorie_user.php"))

    URLSession.shared.dataTask(with: request, completionHandler: {
    [unowned self] data, response, error in

    if let error = error {
    if let response = response {
    print(error, response)

    // handle and display error using response data

    do {

    Data = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response)

    } catch let error as! Error {

    reponseError = error
    Data = nil

    }

    if ( Data != nil ) {

    let res = response as! HTTPURLResponse!;

    if ((response?.statusCode)! >= 200 && (response?.statusCode)! < 300) {
    let responseData:String = String(data:Data!, encoding:String.Encoding(rawValue: String.Encoding.utf8.rawValue))!
    NSLog("Response ==> %@", responseData);

    let jsonData:NSDictionary = try JSONSerialization.jsonObject(with: Data!, options:JSONSerialization.ReadingOptions.mutableContainers ) as! NSDictionary

    let success:NSInteger = jsonData.value(forKey: "success") as! NSInteger

    NSLog("Success: %ld", success);

    }

    if(success == 1) {

    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is saved in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)

    }
    }
    return // rien d'autre à  faire
    }

    var error:String

    if jsonData["error_message"] as? String != nil {

    error_msg = jsonData["error_message"] as! String

    } else {

    error = "Unknown Error"

    }
    print(error)

    // handle and display error

    return // rien d'autre à  faire
    }

    if data != nil // bonne réponse, article trouvé
    {
    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)
    }
    }).resume()
    }

    Mais j'ai cette erreur  :



    /Users/Desktop/dossier sans /DetailForRentTableViewController.swift:145:70: Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(Data?, URLResponse?, Error?) -> Void'

    j'espère avoir bien compris???

  • Joanna CarterJoanna Carter Membre, Modérateur
    En bref, non, pas du tout. Je suis actuellement loin de mon ordi. Je te répondrai plus tard
  • LarmeLarme Membre

    Aouch.



    let myURLRequest = ...
    URLSession.shared.dataTask(request:myURLRequest, completionHandler:{
        data, response, error in
        Data =  NSURLConnection.sendSynchronousRequest(myURLRequest...)   
    }.resume()

    J'ai pas regarder le reste, mais ça me pose beaucoup de souci ça. 


     


    Pourtant, tu sembles déjà  utiliser URLSession, notamment pour les images, donc tu sembles comprendre que cela fait déjà  une requête ça. Alors pourquoi est-ce que dedans tu fais NSURLConnection.sendSynchronousRequest sur la même URLRequest?


    Tu as déjà  effectué la requête, tu as déjà  data, response et error !


    Regarde juste s'il y a error est non nil. Ensuite, regarde le status code potentiel de response. Ensuite, bah lis data.


  • easydeasyd Membre
    mai 2017 modifié #23

    je vient de faire la modification 



    @IBAction func favories() {

    let request = URLRequest(url: URL(fileURLWithPath: "http://lien_serveur/myfavorie_user.php"))

    URLSession.shared.dataTask(with: request, completionHandler: {
    [unowned self] data, response, error in

    if let error = error {
    if let response = response {
    print(error, response)

    // handle and display error using response data


    if ((response?.statusCode)! >= 200 && (response?.statusCode)! < 300) {
    let responseData:String = String(data:Data!, encoding:String.Encoding(rawValue: String.Encoding.utf8.rawValue))!
    NSLog("Response ==> %@", responseData);

    let jsonData:NSDictionary = try JSONSerialization.jsonObject(with: urlData!, options:JSONSerialization.ReadingOptions.mutableContainers ) as! NSDictionary

    let success:NSInteger = jsonData.value(forKey: "success") as! NSInteger

    NSLog("Success: %ld", success);

    }

    if(success == 1) {

    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is saved in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)

    }
    return // rien d'autre à  faire
    }

    var error:String

    if jsonData["error_message"] as? String != nil {

    error_msg = jsonData["error_message"] as! String

    } else {

    error = "Unknown Error"

    }
    print(error)

    // handle and display error

    return // rien d'autre à  faire
    }

    if data != nil // bonne réponse, article trouvé
    {
    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment: "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)
    }
    }).resume()
    }


    Merci a toi,


  • easydeasyd Membre

    Avez-vous un exemple.


     


    Qui explique la fonction.


    Je suis désoler mes je comprend que de cette façon.


     


    je n'arrive pas a assimiler cette logique que demande Apple, sous php je rencontre pas trop de problème de dev et je vais plus vite mais là  je suis perdu et je reste avec mes frustration.


  • LarmeLarme Membre

    Quelle fonction ? Quelle partie exactement ?


  • easydeasyd Membre

    Voilà  comment j'ai fait avec des commentaire :



    @IBAction func favories() {

    let request = URLRequest(url: URL(fileURLWithPath: "")) //lien vers monfichier.php

    URLSession.shared.dataTask(with: request, completionHandler: // ouvre la sessions de connexion
    {
    [unowned self] data, response, error in

    if let error = error // vérifie si error contient une valeur.
    {
    if let response = response // vérifie si response contient une valeur.
    {
    print(error, response)

    // Ici je récupere la réponse

    if ((res?.statusCode)! >= 200 && (res?.statusCode)! < 300)
    {
    let responseData:String = String(data:urlData!, encoding:String.Encoding(rawValue:
    String.Encoding.utf8.rawValue))!

    NSLog("Response ==> %@", responseData);

    let jsonData:NSDictionary = try JSONSerialization.jsonObject(with: urlData!,
    options:JSONSerialization.ReadingOptions.mutableContainers ) as! NSDictionary

    let success:NSInteger = jsonData.value(forKey: "success") as! NSInteger

    NSLog("Success: %ld", success);
    // handle and display error using response data

    }

    if(success == 1) { // j'affiche la réponse si elle est success 1 enregistrement réussi

    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is saved in your favorite", comment:
    "Please_enter_all_fields")

    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)

    }
    return // rien d'autre à  faire
    }

    print(error)

    //ici je gère les erreurs repose serveur si rien pas de json.

    var error_msg:String

    if jsonData["error_message"] as? String != nil {
    error_msg = jsonData["error_message"] as! String
    } else {
    error_msg = "Unknown Error"
    }

    return // rien d'autre à  faire

    }

    if data != nil // nil contient pas de réponse vide d'affiche texte que cela existe déjà .
    {
    let title = NSLocalizedString("FAVORITE", comment: "TITLE")
    let msg = NSLocalizedString("Your ad is already registered in your favorite", comment:
    "Please_enter_all_fields")
    let alert = UIAlertController.init(title: title, message: msg, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))

    self.present(alert, animated: true, completion: nil)
    }
    }).resume()
    }

    j'espère que cela va.


  • Joanna CarterJoanna Carter Membre, Modérateur

    Bah non !


     


    Est-ce que tu as essayé de lire les docs sur URLSession, HTTPURLResponse et les autres types qui s'utilisent ici ?



    @IBAction func favories()
    {
    let request = URLRequest(url: URL(fileURLWithPath: "")) //lien vers monfichier.php

    // Créer la session et la tâche pour récupérer les données
    URLSession.shared.dataTask(with: request, completionHandler:
    {
    [unowned self] data, response, error in // response est un HTTPURLResponse

    if let error = error
    {
    // error n'est pas nil ; donc il y avait une erreur
    // tu peux accéder error pour plus d'infos

    if let response = response
    {
    // response n'est pas nil
    // en plus des infos dans error, le statusCode se trouve dans response

    // utilises les infos dans error et response pour présenter un message d'erreur
    // ne touches pas data

    return // rien d'autre à  faire
    }

    // ce n'est pas nécessaire de toucher data ici

    return // rien d'autre à  faire
    }

    if data != nil
    {
    // data n'est pas nil ; donc pout pouvez réagir comme attendu
    // si une bonne réponse signifie que l'article existe déjà ,
    // présenter un message ici
    }
    }).resume() // activer la tâche
    }



    Avez-vous un exemple.


     


    Qui explique la fonction.


    Je suis désoler mes je comprend que de cette façon.


     


    je n'arrive pas a assimiler cette logique que demande Apple, sous php je rencontre pas trop de problème de dev et je vais plus vite mais là  je suis perdu et je reste avec mes frustration.




     


     


    Tu ne travaille pas en php. La programmation "native" est tout différente. Il faut étudier, pas seulement comment copier/coller le code des autres, mais comment programmer toi-même.


     


    Encore une fois, je t'ai donné' du code. Encore une fois dans le code que tu as montré en réponse, tu as utilisé une ligne comme :



    if ((res?.statusCode)! >= 200 && (res?.statusCode)! < 300)

    ... qui utilise les "!", même après les interdictions innombrables


     


    Oh, et si tu voulais faire quelque chose comme ça, tu pourrais le simplifier comme :



    if 200 ..< 300 ~= response.statusCode

    À la place de continuer de copier/coller le code des autres, sans comprehension, je te conseillerais d'abandonner ton projet jusqu'à  tu as compris comment coder en Swift et comment lire les docs sur les APIs que tu veuilles utiliser.


  • easydeasyd Membre
    Bonjour tous le monde,


    Je te remerci de ta franchisse, quant j'ai appris le php je rencontré les même difficulté et maintenant je m'en sort au jourd'hui avec quelques projets qui tourne.

    Ici j'ai du mal, même quant j'avais commancer à  faire du C pur et dur dans mes étude de réseau.


    Je vais et voudrai terminer ce projet, c'est pour moi un exploi et m'avous pas vaincu. Si non c'est un échec.


    Je vous remerci de vos aides que vous m'avais apporter tous au long de ces mois et je serai reconnaissant de tous.

    Je vous importunerai plus et vais continuer mon projet.


    Merci à  vous, et continuer comme cela kiss à  aider les autre.
  • Joanna CarterJoanna Carter Membre, Modérateur

    Malheureusement, Swift est, au même temps, similaire de C et tout différent de C.


     


    En Swift, il y a une base de C mais, après ça, plusieurs qualités additionnelles.


     


    Tu as eu pas mal de soucis avec les "!" ; peut-être je peux expliquer pourquoi avec quelque chose comme le fameux :



    let priceString = (person["price"] as? String)!

    En -Swift, tu as le concept des valeurs optionnelles ; du coup, tu pourrais définir une var comme :



    var priceString: String?

    ... et il ne faut pas l'initialiser parce que, implicitement, sa valeur est nil par défaut.


     


    Si tu ne connaissais pas si priceString a été assigné une valeur ou non, tu pourrais l'accéder comme :



    var aString: String

    if priceString != nil
    {
    aString = priceString!
    }

    Oui, j'ai utilisé un "!" mais c'est seulement parce que j'ai auparavant vérifié que priceString n'est pas nil.


     


    Mais, sans cette vérification, si j'avais écrit :



    var aString: String = priceString!

    ... ça pourrait échouer lors de l'exécution dans le cas que priceString soit nil.


     


    Dans ton code :



    let priceString = (person["price"] as? String)!

    ... qu'est-ce qui se passe ?


     


    person["price"] renvoie Any? ; c'est à  dire que la valeur puisse être non-nil et de n'importe-quel type ou, qu'elle puisse être nil.


     


    Donc, si j'ai bien deviné, tu as saisi quelque chose comme :



    let priceString: String = person["price"] as? String

    ... et le compilateur t'a donné le message "Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?"


     


    Puis tu as accepté la proposition d'un "Fix-it" d'introduire un "!" comme :



    let price: String = person["price"]! as? String

    Ce qui t'aurais donné encore le même message mais avec un "Fix-it" de "Replace "person["price"]! as? String" with "(person["price"]! as? String)!"


     


    Oui, tu as suivi les conseils du compilateur en acceptant le "Fix-it". Le code est compilé. Tout ira bien ??? Pas du tout !!!


     


    En exécutant le code, ça pourrait arriver que person["price"] n'existe pas dans le dictionnaire ; du coup - Boummm ! L'appli s'échoue est disparaà®t devant l'utilisateur. Ce qui n'est pas cool ; ce qui est "very bad" !


     


    C'est pour éviter ça que je t'ai conseillé plusieurs fois d'arrêter d'écrire cette façon de code.


     


    Comme j'ai déjà  dit, les "subscripts" comme person["price"] renvoie une valeur optionnelle - soit une valeur, soit nil ; ce que tu ne peux pas anticiper lorsque tu écris le code ; par conséquence tu dois, impérativement, le tester pour nil.


     


    En plus, il faut réfléchir sur ce que tu fasses dans le cas échéant. Si il n'y a aucune valeur, qu'est-ce que présentes à  l'utilisateur ?


     


    Dans le cas de cet exemple, on a essayé d'assigner le résultat vers une var de type String (non-optionnelle) et c'est ça qui a provoqué la colère du compilateur.


     


    Dans ce cas, il faut prendre les précautions. Tout d'abord, il faut vérifier que person["price"] existe dans le dictionnaire. Avec Swift, on peut faire la vérification et, si il y a bien une valeur dans le dictionnaire, l'assigner au même temps.



    if let priceAsAny = person["price"]
    {
    // une valeur pour le clé "price" existe dans le dictionnaire
    // et elle a été assignée à  priceAsAny

    }
    else
    {
    // il n'y a aucune valeur pour le clé "price"
    }

    Maintenant, tu connais qu'il y a une valeur mais tu ne sais pas encore de quel type.


     


    Si tu faisais quelque chose comme :



    if let priceAsAny = person["price"] as? String
    {
    ...
    }
    else ...

    ... ça pourrait passer par le "else" mais tu ne sauras pas la raison. C'était parce que il n'y avait aucune valeur ? Ou parce que il y avait une valuer mais elle n'était pas un String ?


     


    Du coup, il faut faire les deux vérifications en deux étapes :



    if let priceAsAny = person["price"]
    {
    if let priceString = priceAsAny as? String
    {
    // ici tu es sûr que priceString contient une valeur qui est un String
    }
    }
    else
    {
    // il n'y a aucune valeur pour le clé "price"
    }

    Oui, c'est beaucoup plus de code mais tu ne risque pas de déplaire tes utilisateurs quand ton appli se plante.


     


    Or, nous avons parlé d'assigner une valeur qui provient d'un dictionnaire vers un String, avec tous les vérifications qui s'entrainent.


     


    Mais, pour les occasions lorsque tu veux assigner la valeur dans le dictionnaire, en attendant qu'elle soit un String? (optionnelle), tu pourrais cout-circuiter un peu.


     


    Si tu voulais assigner le valeur directement vers un UILabel, la propriété myLabel.text est de type String? (optionnelle) ; du coup, tu peux bien faire :



    priceLabel.text = person["price"] as String?

    Dans ce cas :


     


    1. si person["price"] renvoie nil, c'est bon parce que priceLabel.text accepte nil et la UILabel s'affiche comme vide.


     


    2. s'il y a une valeur mais ell n'est pas un String?, c'est le même résultat.


     


    Pour l'appli que tu essaies de faire, avec tous ces appels à  un serveur, il te faut étudier plus sur les APIs comme URLSession, éviter d'utiliser les APIs deprecated, et prendre compte de la synchrone en faisant les appels asynchrones, en cas que l'utilisateur puisse perdre réseau à  tout moment et ça puisse bloquer l'appli pour quelques minutes.


     


    Continues à  faire les petits pas et de nous dire comment ça passe. On est là  pour t'aider mais il faut essayer d'être un meilleur apprenti  8--)


  • easydeasyd Membre

    :D  Bonjour et merci a toi pour tes conseilles très chaleureux.


     


    Je vais faire de effort dans ce sens.

  • easydeasyd Membre

    Voilà ,


     


    Je vient de faire cela :



    if let priceAsAny = person["price"]
    {
    if let priceString = priceAsAny as? String
    {
    ui_pric1 = priceString

    let number = NSDecimalNumber(string: ui_pric1)

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = 0
    formatter.locale = Locale(identifier: "fr_FR")
    let nombre = formatter.string(from: number)

    print(nombre!)

    pr.text = nombre!

    } else {
    pr.text = "pas de Prix"
    }
    }

    Et ça fonctionne très bien,


     


    Merci,


Connectez-vous ou Inscrivez-vous pour répondre.