message d'erreur

jean-lucjean-luc Membre
février 2017 modifié dans API UIKit #1

Bonjour,


après une requête  du type "getUrl" avec cette adresse "http://adresseIP/donnees_Bdd.php", j'arrive à  récupérer des données d'une bdd sous forme d'une variable String.


 


​Mais si j'ajoute le code pour afficher ces variables dans les labels, mon programme met environ une vingtaine de seconde avant de m'afficher les labels avec une bonne dizaine de fois le code suivant



2017-02-15 14:12:38.949 accèsBdd[934:100465] This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
Stack:(
0 CoreFoundation 0x000000010889ed4b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000105bb121e objc_exception_throw + 48
2 CoreFoundation 0x00000001089082b5 +[NSException raise:format:] + 197
3 Foundation 0x00000001058ab06c _AssertAutolayoutOnAllowedThreadsOnly + 180
4 Foundation 0x00000001056cc334 -[NSISEngine withBehaviors:performModifications:] + 31
5 UIKit 0x0000000106a4786e -[UIView(UIConstraintBasedLayout) _resetLayoutEngineHostConstraints] + 76
6 UIKit 0x0000000106145a8b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1192
7 QuartzCore 0x000000010b6debf8 -[CALayer layoutSublayers] + 146
8 QuartzCore 0x000000010b6d2440 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
9 QuartzCore 0x000000010b6d22be _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
10 QuartzCore 0x000000010b660318 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 280
11 QuartzCore 0x000000010b68d3ff _ZN2CA11Transaction6commitEv + 475
12 QuartzCore 0x000000010b68d87d _ZN2CA11Transaction14release_threadEPv + 593
13 libsystem_pthread.dylib 0x0000000109bad3dc _pthread_tsd_cleanup + 555
14 libsystem_pthread.dylib 0x0000000109bacf63 _pthread_exit + 117
15 libsystem_pthread.dylib 0x0000000109bab582 pthread_attr_getschedpolicy + 0
16 libsystem_pthread.dylib 0x0000000109ba9341 start_wqthread + 13

Réponses

  • Met nous du code, ça sera peut-être plus compréhensible et on trouvera l'erreur plus simplement ^^


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #3
    De mon avis tu appelles du code de processing dans un thread arrière-plan et tu essaies de mettre à  l'UI du même thread, à  la place de l'appeler sun le thread principal.
  • L'erreur t'explique que tu essayes de changer ton UI dans un thread autre que le principal.


     


    Tout ce qui implique changement UI doit se faire seulement et uniquement dans le main thread. Sinon tu as des latences ou ire un crash.


  • jean-lucjean-luc Membre
    février 2017 modifié #5

    voilà  le code complet


    c'est lorsque j'ajoute les 2 lignes rouges que le problème apparaà®t



    import UIKit

    class ViewController: UIViewController {

    var responseCode: String = ""
    var portailEtat: String = ""
    var garageEtat: String = ""

    @IBOutlet weak var portailLabel: UILabel!
    @IBOutlet weak var garageLabel: UILabel!
    let adressePhp: String = "http://adresseIP/donnees_Bdd.php"

    override func viewDidLoad() {
    super.viewDidLoad()
    }

    //Marque requête http

    func getURL(getAdresse: String) {

    let url = URL(string: getAdresse)

    var urlRequest = URLRequest(url: url!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 30)
    urlRequest.httpMethod = "GET"
    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest) { (data, urlResponse, err) in

    if let _ = err {
    // gérer l'erreur
    }
    if data != nil {
    //gérer la reponse
    let response = String(data: data!, encoding: .utf8)!
    self.responseCode = response
    //print(response)
    self.decomposeResponseCode(code: response)
    }
    }
    task.resume()
    }

    func decomposeResponseCode(code: String) {
    print("debut code")
    //print(code)
    print("fin code")
    let startIndex1 = code.index(code.startIndex, offsetBy: 331)
    let endIndex1 = code.index(code.startIndex, offsetBy: 345)
    portailEtat = code[startIndex1...endIndex1]
    print(portailEtat)
    portailLabel.text = portailEtat
    let startIndex2 = code.index(code.startIndex, offsetBy: 349)
    let endIndex2 = code.index(code.startIndex, offsetBy: 369)
    garageEtat = code[startIndex2...endIndex2]
    print(garageEtat)
    garageLabel.text = garageEtat
    }

    @IBAction func miseAJourAction(_ sender: UIButton) {
    getURL(getAdresse: adressePhp)
    }

    }
  • Joanna CarterJoanna Carter Membre, Modérateur

    Et, ça y est !



    let task = session.dataTask(with: urlRequest)
    {
    (data, urlResponse, err) in

    if let _ = err
    {
    // gérer l'erreur
    }

    if data != nil
    {
    //gérer la reponse
    let response = String(data: data!, encoding: .utf8)!

    self.responseCode = response

    //print(response)
    self.decomposeResponseCode(code: response)
    }
    }

    Tu appelles self.decomposeResponseCode dans le thread d'exécution du dataTask.


     


    Il faut, plutôt quelque chose comme :



    let task = session.dataTask(with: urlRequest)
    {
    (data, urlResponse, err) in

    if let _ = err
    {
    // gérer l'erreur
    }

    if data != nil
    {
    //gérer la reponse
    let response = String(data: data!, encoding: .utf8)!

    self.responseCode = response

    //print(response)
    DispatchQueue.main.async
    {
    [unowned self] in

    self.decomposeResponseCode(code: response)
    }
    }
    }

  • portailLabel.text = portailEtat 

    Tu modifies l'UI. Cela doit se faire uniquement dans le mainthread, d'où l'erreur.


     


    Donc, decomposeResponseCode(code:) est appelée dans la closure de  dataTask(with:) {} Mais qui a dit que cette closure s'effectuait dans le main thread ?


     


    Donc dans cette closure, quand tu vas appeler une modification de l'UI mets ça là -dedans :



    ​DispatchQueue.main.async {
    }
  • Joanna CarterJoanna Carter Membre, Modérateur

    @Larme - grillé !  ::)


  • c'est corrigé


    Merci pour vos aides.


    Il y'a des jours ou je trouve que c'était plus facile de construire des ponts en béton  ::)


    Jean-Luc


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