(Réglé) Traitement d'une requête très long (presque 20 secondes)

Ben77650Ben77650 Membre
juillet 2014 modifié dans API AppKit #1

Bonjour à  tous,


 


Je viens vers vous car j'ai un souci, j'ai une requête qui met presque 20 secondes a s'exécuter (alors qu'elle est toute simple), et soyons clair n'importe quel utilisateur n'attendra pas 20 secondes...


 


A titre de comparaison une autre requête me prends 8 sec (et mon boss trouve ça déjà  très long)


 


Ci joint mon code:



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title=@Mon compte;
    }
    
    loadingView = [[UIView alloc] initWithFrame:CGRectMake(75, 200, 170, 170)];
    loadingView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    loadingView.clipsToBounds = YES;
    loadingView.layer.cornerRadius = 10.0;
    
    actview = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    actview.frame = CGRectMake(65, 20, actview.bounds.size.width, actview.bounds.size.height);
    [loadingView addSubview:actview];
    
    loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 80, 140, 22)];
    loadingLabel.backgroundColor = [UIColor clearColor];
    loadingLabel.textColor = [UIColor whiteColor];
    loadingLabel.adjustsFontSizeToFitWidth = YES;
    loadingLabel.text = @Récupération de vos données. Veuillez patientez svp...;
    loadingLabel.lineBreakMode = NSLineBreakByWordWrapping;
    loadingLabel.numberOfLines=0;
    loadingLabel.textAlignment = NSTextAlignmentCenter;
    [loadingLabel sizeToFit];
    [loadingView addSubview:loadingLabel];
    [self.view addSubview:loadingView];
    [actview startAnimating];

    
    [self getMemberInfo];
    
    return self;
}


-(void)getMemberInfo
{
    dispatch_queue_t downloadQueue = dispatch_queue_create("Get Member Infos", NULL);
    
    dispatch_async(downloadQueue, ^{
        NSData *result = [self searchMemberInfo];
        id strResult=nil;
        int cpt;
        NSError* error;
        strResult = [NSJSONSerialization JSONObjectWithData:result options:0 error:&error];
        
        _liste = [[NSMutableArray alloc]init];
        
        for(cpt=0; cpt<[strResult count];cpt++)
        {
            NSDictionary *dicoTemp = [strResult objectAtIndex:cpt];
            NSMutableArray* arrayTemp = [[NSMutableArray alloc]init];
            
            [arrayTemp addObject:[dicoTemp objectForKey:@myCivilitu]];                  //0
            [arrayTemp addObject:[dicoTemp objectForKey:@mySurname]];                       //1
            [arrayTemp addObject:[dicoTemp objectForKey:@myFirstName]];                    //2
            [arrayTemp addObject:[dicoTemp objectForKey:@myAdress]];                   //3
            [arrayTemp addObject:[dicoTemp objectForKey:@myZip]];                  //4
            [arrayTemp addObject:[dicoTemp objectForKey:@myCity]];                     //5
            [arrayTemp addObject:[dicoTemp objectForKey:@myTelephone]];                       //6
            [arrayTemp addObject:[dicoTemp objectForKey:@myEmail]];                     //7
        }
        
        if(_liste.count!=0)
        {
        [actview stopAnimating];
        [loadingView removeFromSuperview];
            
        _civilite.text=[[_liste objectAtIndex:0]objectAtIndex:0];
        _nom.text=[[_liste objectAtIndex:0]objectAtIndex:1];
        _prenom.text=[[_liste objectAtIndex:0]objectAtIndex:2];
        _region.text=@"";
        _dep.text=@"";
        _adresse.text=[[_liste objectAtIndex:0]objectAtIndex:3];
        _cp.text=[[_liste objectAtIndex:0]objectAtIndex:4];
        _ville.text=[[_liste objectAtIndex:0]objectAtIndex:5];
        _tel.text=[[_liste objectAtIndex:0]objectAtIndex:6];
        _mail.text=email;
        }

    });
}


- (NSData *)searchMemberInfo {
    
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@%@", @http://www.mywebsite.org/getInfos.php]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    NSString *requestFields = @"";
    requestFields = [requestFields stringByAppendingFormat:@pwd=%@&;", password];
    requestFields = [requestFields stringByAppendingFormat:@admail=%@", email];
    
    requestFields = [requestFields stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData *requestData = [requestFields dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBody = requestData;
    request.HTTPMethod = @POST;
    
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if (error == nil && response.statusCode == 200) {
    }
    else {
    }
    
    return responseData;
}


NSLog(@liste: %@", _liste);


2014-05-20 10:31:59.422 MyApp[4294:4b13] liste: (


        (


        Mme,


        Renault,


        "M\U00e9gane",


        "Place de Clichy",


        75013,


        "Paris, France",


        0836656565,


        "toto@toto.com",


    )


)


 



 


«134

Réponses

  • LarmeLarme Membre

    Y'a un outil dans Intruments pour voir qu'est-ce qui prend exactement du temps si je me souviens bien.


    Cela pourrait t'aider à  voir qu'est-ce qui prends exactement du temps. Dès lors, on pourra penser à  peut-être optimiser...


  • muqaddarmuqaddar Administrateur

    Oui, il faudrait savoir si c'est le serveur ou la base sur le serveur... 


    Si tu as des logs côté serveur...


  • D'abord merci de chercher à  m'aider


     


    Je ne pense pas que ce soit le serveur, car de ce que me dit mon boss, c'est bien plus rapide sur l'application Android qui se connecte au même serveur (concernant la partie ou moi je met 8 sec, sur Android il met 0.5 sec à  tout récupérer...)


     


    Et je ne trouve déjà  pas "Instruments" alors je parle même pas de l'outil


  • AliGatorAliGator Membre, Modérateur
    mai 2014 modifié #5

    Mon dieu, "sendSynchronousRequest"... faut pas chercher plus loin.


     


    Oui je sais tu as mis tout ça dans une dispatch_queue, mais ça n'empêche, les NSURLConnection sont gérées par la RunLoop et non pas par un WorkingThread, donc faut utiliser ce qui est fait pour pour les gérer de façon asynchrone...


    Créer une queue tout ça pour appeler du code synchrone, alors qu'il y a déjà  des méthodes asynchrones pour ça est une très mauvaise idée. D'autant que la méthode de base est la méthode asynchrone, et que la méthode synchrone appelle la méthode asynchrone avec des semaphores pour bloquer l'exécution, donc avec ta dispatch_queue tu essayes de... rendre asynchrone un truc qui rend synchrone un truc qui est asynchrone... ou comment se compliquer la vie.


     


    Enlève-moi ce sendSynchronousRequest et cette downloadQueue et fais les choses bien et comme conseillées dans le URL Loading Programming Guide et le Concurrency Programming Guide, en utilisant les méthodes asynchrones existantes pour faire de l'asynchrone, à  savoir sendAsynchronousRequest.


     


    Je suis quasiment sûr qu'avec ça tes temps de réponse vont drastiquement être réduits.


  • Ali merci pour cette réponse.


     


    Mon prof d'iOS de cette année (un ancien étudiant, possédant son entreprise) nous avais dit d'utiliser cette méthode sendSynchronousRequest dans une Queue (je viens de vérifier sur son PDF la). Encore heureux que tu me dise cela, je n'utilise quasiment que cela.


     


    Ne connaissant pas ces guide, peut tu me dire les bonnes manières de faire s'il te plait ?


  • AliGatorAliGator Membre, Modérateur
    mai 2014 modifié #7
    Va peut-être falloir que ton prof révise un peu ses concepts concernant l'utilisation du SDK et des API existantes plutôt que d'essayer de réinventer la roue (et le faire de la mauvaise manière pour ce cas particulier).
    Oui les dispatch_queue sont la méthode à  utiliser pour faire des tâches en arrière plan en général (GCD c'est le pied)... sauf pour les tâches comme NSURLConnection qui se basent sur la RunLoop et ont surtout déjà  une API pour faire de l'asynchrone, qui prend en compte la manière un peu spécifique dont fonctionne NSURLConnection.



    Sinon concernant les guides, il suffit de chercher leurs noms sur Google.

    Rely on the system frameworks whenever possible. The best way to achieve concurrency is to take advantage of the built-in concurrency provided by the system frameworks. Many frameworks use threads and other technologies internally to implement concurrent behaviors. When defining your tasks, look to see if an existing framework defines a function or method that does exactly what you want and does so concurrently. Using that API may save you effort and is more likely to give you the maximum concurrency possible.

  • D'accord merci et tiens voila le pdf de mon prof, si tu as d'autres améliorations / rectifications / conseils je suis preneur.


     


    Merci ;)


  • AliGatorAliGator Membre, Modérateur
    mai 2014 modifié #9
    Ah oui je vois d'autres fautes !

    Entre autres, en plus de l'hérésie dont j'ai parlé au dessus concernant sendSynchronousRequest (à  banir sans se poser de question, en aucun cas utiliser cette méthode, je me demande même pourquoi Apple la garde encore), je vois des trucs sur dispatch_get_current_queue, alors qu'il est à  éviter.

    D'ailleurs, dispatch_get_current_queue n'existait (à  l'époque) que pour du debug, et à  ne pas utiliser en production (c'est clairement indiqué dans sa doc). Et de toute façon maintenant il a été totalement supprimé de l'API (vu que Apple a réalisé que bcp l'utilisaient à  tort).

    D'ailleurs le fait d'avoir à  savoir quelle est la dispatch_queue courante et souvent un signe qu'on n'a pas forcément compris la subtile différence entre les dispatch_queue et les threads (une dispatch_queue peut dispatcher les blocks qu'on lui soumet sur différents threads, une queue ne pilote pas forcément qu'un thread).
    Normalement tu n'as pas de raison d'avoir à  connaà®tre quelle est la dispatch_queue courante, la seule chose utile à  connaà®tre éventuellement c'est si [NSThread isMainThread] pour savoir si tu as besoin de dispatch_(a)sync(dispatch_get_main_queue(), ^{...}) ton code UI-related ou si tu es déjà  sur le MainThread et que tu peux l'exécuter direct.
  • Merci pour ces conseils en tout cas Ali, je prends bien note ;)


  • Ben77650Ben77650 Membre
    mai 2014 modifié #11

    On est bien d'accord que la bonne manière de faire est celle la ?



    - (void)searchMemberInfo {
        
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@%@", @http://www.monsite.org/getInfos.php]];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        NSString *requestFields = @"";
        requestFields = [requestFields stringByAppendingFormat:@pwd=%@&;", password];
        requestFields = [requestFields stringByAppendingFormat:@admail=%@", email];
        
        requestFields = [requestFields stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSData *requestData = [requestFields dataUsingEncoding:NSUTF8StringEncoding];
        request.HTTPBody = requestData;
        request.HTTPMethod = @POST;
        
        NSHTTPURLResponse *response = nil;
        NSError *error = nil;
        [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            if ([data length] >0 && error == nil)
            {
                
                // DO YOUR WORK HERE
                
                id strResult=nil;
                int cpt;
                NSError* erreur;
                strResult = [NSJSONSerialization JSONObjectWithData:data options:0 error:&erreur];
                
                _liste = [[NSMutableArray alloc]init];
                
                for(cpt=0; cpt<[strResult count];cpt++)
                {
                    NSDictionary *dicoTemp = [strResult objectAtIndex:cpt];
                    NSMutableArray* arrayTemp = [[NSMutableArray alloc]init];
                    
                    [arrayTemp addObject:[dicoTemp objectForKey:@laCivilite]];                  //0
                    [arrayTemp addObject:[dicoTemp objectForKey:@leNom]];                       //1
                    [arrayTemp addObject:[dicoTemp objectForKey:@lePrenom]];                    //2
                    [arrayTemp addObject:[dicoTemp objectForKey:@lAdresse]];                   //3
                    [arrayTemp addObject:[dicoTemp objectForKey:@leCodePostal]];                  //4
                    [arrayTemp addObject:[dicoTemp objectForKey:@laVille]];                     //5
                    [arrayTemp addObject:[dicoTemp objectForKey:@leTelephone]];                       //6
                    [arrayTemp addObject:[dicoTemp objectForKey:@lEmail]];                     //7
                    [arrayTemp addObject:[dicoTemp objectForKey:@type]];                      //8
                }
                
                if(_liste.count!=0)
                {
                    //NSLog(@liste: %@", _liste);
                    
                    [actview stopAnimating];
                    [loadingView removeFromSuperview];
                    
                    _civilite.text=[[_liste objectAtIndex:0]objectAtIndex:0];
                    _nom.text=[[_liste objectAtIndex:0]objectAtIndex:1];
                    _prenom.text=[[_liste objectAtIndex:0]objectAtIndex:2];
                    _adresse.text=[[_liste objectAtIndex:0]objectAtIndex:3];
                    _cp.text=[[_liste objectAtIndex:0]objectAtIndex:4];
                    _ville.text=[[_liste objectAtIndex:0]objectAtIndex:5];
                    _tel.text=[[_liste objectAtIndex:0]objectAtIndex:6];
                    _mail.text=email;
                }

                
            }
            else if ([data length] == 0 && error == nil)
            {
                NSLog(@Nothing was downloaded.);
            }
            else if (error != nil){
                NSLog(@Error = %@", error);
            }
        }];
    }

    Je ne comprends pas pourquoi "request" vaut " http://www.monsite.org/getInfos.php" et non "http://www.monsite.org/getInfos.php?pwd=password&admail=email"


  • AliGatorAliGator Membre, Modérateur
    Oui c'est bien comme ça qu'il faut faire.

    Quoique pour le paramètre "queue" de "sendAsynchronousRequest:queue:completionHandler:" tu pourrais mettre [NSOperationQueue mainQueue] car ici la NSOperationQueue qui est passée à  ce paramètre (comme expliqué dans la doc) c'est la queue sur laquelle le code de ton completionHandler va être exécuté, pas la queue sur laquelle ta requête réseau va être exécutée, donc c'est pas forcément la peine d'avoir une NSOperationQueue d'arrière-plan pour ce que tu fais dedans, mais bon du moment que tu ne fais pas d'UI dans ton completionHandler ça va encore.

    Pourquoi tu voudrais que l'URL de ta NSRequest ait ce contenu ? C'est pas ce que ton code demande.
    Ton code demande d'encoder "pwd=password&admail=email" dans le HTTPBody (ce qui est logique si ta requête est du POST), donc ce "pwd=password&admail=email" est présent dans le corps de la requête POST, pas dans l'URL. C'est pas comme si tu faisais du GET, là  tu utilises le HTTPBody pour passer tes paramètres donc rien de plus normal que ton URL, elle, ne change contienne pas ces paramètres car ce n'est pas ce que tu as demandé.
  • Ben77650Ben77650 Membre
    mai 2014 modifié #13

    Bah en fait ça me chagrine, car mes labels restent avec la valeur par défaut, donc je me suis dit que l'erreur venait peut être de la mais visiblement c'est pas le cas.


     


    Je continue de chercher, si jamais vous voyez faites moi signe.


     


    Ps: J'ai juste modifié et changé en "[self searchMemberInfo];" dans initWithNibName


     


     


     


    Edit: Chose étonnante ma liste est tout le temps vide, bizarre quand j'utilisais la manière synchrone avec une manière identique ça fonctionnait


     


    Edit 2: Bon visiblement il ne rentre jamais dans la boucle for


     


    Edit 3: ma variable strResult est vide, WTF ?


     


    Edit 4: Si dans strResult, je remplace "data" par "requestData" ça m'affiche null


     


    Edit 5: Data m'affiche <5b5d>


  • AliGatorAliGator Membre, Modérateur
    ... completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
    Si data est nil, c'est soit que ton serveur te retourne effectivement du vide (page vierge), soit qu'il y a eu une erreur. Regarde la valeur de connectionError, et regarde aussi ce qui t'es renvoyé dans la réponse (genre response.statusCode, response.allHTTPHeaders, etc) pour comprendre ce qui se passe. Peut-être que dans ton test tu ne passes pas bien le password et que du coup ton serveur de renvoie une erreur?
  • Data n'est pas vide (cf edit 5), en revanche requestData l'est lui


     


    J'avais prévu le coup et déjà  fait les logs suivants



            NSLog(@Réponse: %@",response);
            NSLog(@Erreur: %@",error);
            NSLog(@Erreur de connexion: %@",connectionError);
            NSLog(@Données: %@",data);


    2014-05-20 16:10:58.720 App[2395:60b] Réponse: <NSHTTPURLResponse: 0x8fa76a0> { URL: http://www.monsite.org/getInfos.php } { status code: 200, headers {


        Connection = close;


        "Content-Type" = "text/html";


        Date = "Tue, 20 May 2014 14:10:59 GMT";


        Server = Apache;


        "Transfer-Encoding" = Identity;


        "X-Powered-By" = PleskLin;


    } }


    2014-05-20 16:10:58.721 App[2395:60b] Erreur: (null)


    2014-05-20 16:10:58.722 App[2395:60b] Erreur de connexion: (null)


    2014-05-20 16:10:58.722 App[2395:60b] Données: <5b5d>


     


  • AliGatorAliGator Membre, Modérateur
    <5b5d> veux dire que data contient 2 octets, de code ascii 0x5B et 0x5D. Or ce sont les codes ascii de [ et ] respectivement.

    Autrement dit, ton serveur te renvoie une réponse "200 OK", avec un JSON tout à  fait valide. Il se trouve juste que ce JSON qu'il te renvoie correspond à  un tableau totalement vide ("[]").
  • Pourtant mon JSON est pas vide vu qu'il marchais de manière synchrone et que j'y ai pas touché depuis.


     


    Pareil je ne pense pas qu'il y ai d'erreurs dans mon code, j'ai copié collé celui du synchrone qui fonctionnait


  • AliGatorAliGator Membre, Modérateur
    Le fait de juste passer de synchrone à  asynchrone ne peux pas avoir d'impact sur ton résultat d'avoir un JSON vide ou pas vide. Tu as dû changer qqch d'autre (comme la façon de construire ta requête peut-être)
  • AliGatorAliGator Membre, Modérateur
    Au pire tu reset ton GIT au commit juste avant (celui quand tu faisais du synchrone) pour retrouver l'état d'avant, tu rajoutes des logs pour voir la tronche de request, request.HTTPBody, response & co, puis tu restores ton commit où tu as tout migré en sendAsynchronousRequest et tu compares les logs. C'est aussi pour ça que c'est fait GIT ;) (car tu utilises GIT j'espère)
  • Ben77650Ben77650 Membre
    mai 2014 modifié #20
    Bah je suis passé de ça (exemple repris sur un Controller d'Offre)
    - (NSData *)searchOfferKeyword {

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@%@", @http://www.monsite.org/chercherOffres.php]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        NSString *requestFields = @"";
        requestFields = [requestFields stringByAppendingFormat:@nomTable=%@&;", nom_table];
        requestFields = [requestFields stringByAppendingFormat:@limite=%d&, limite];
        requestFields = [requestFields stringByAppendingFormat:@rang=%d&, rang];
        
        requestFields = [requestFields stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSData *requestData = [requestFields dataUsingEncoding:NSUTF8StringEncoding];
        request.HTTPBody = requestData;
        request.HTTPMethod = @POST;
        
        NSHTTPURLResponse *response = nil;
        NSError *error = nil;
        NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if (error == nil && response.statusCode == 200) {
    }
    else {
    }
    return responseData;
    }
    NSData *result = [self searchAllAnnonce];
            
            id strResult=nil;
            int cpt;
            NSError* error;
            strResult = [NSJSONSerialization JSONObjectWithData:result options:0 error:&error];
            
            _liste = [[NSMutableArray alloc]init];
            
            for(cpt=0; cpt<[strResult count];cpt++)
            {
                NSDictionary *dicoTemp = [strResult objectAtIndex:cpt];
                NSMutableArray* arrayTemp = [[NSMutableArray alloc]init];
                
                [arrayTemp addObject:[dicoTemp objectForKey:@someContent]];                         //0
    [arrayTemp addObject:[dicoTemp objectForKey:@someOtherContent]];                         //1
    [arrayTemp addObject:[dicoTemp objectForKey:@someLastContent]];                         //2
                [_liste addObject:arrayTemp];
            }
    à  ce qui est posté dans les messages au dessus (Profil Controller)
     
     
    Edit: Non je n'utilise pas GIT, je suis le seul développeur. En revanche chaque semaine j'enregistre l'état de l'appli, en faisant une sauvegarde
  • AliGatorAliGator Membre, Modérateur

    Edit: Non je n'utilise pas GIT, je suis le seul développeur. En revanche chaque semaine j'enregistre l'état de l'appli, en faisant une sauvegarde

    o_O Je ne vois pas le rapport entre "je suis le seul développeur" et "je n'utilise pas GIT".

    J'utilise GIT sur plein de projets sur lesquels je suis tout seul, et heureusement, car ça m'est extrêmement utile. Justement par exemple pour des cas comme celui que tu as, où on peut facilement avec GIT et ses outils basculer d'une version du code à  l'autre, faire des diff, des bisect, des comparaisons, revenir à  une version le temps de tester puis re-récupérer nos modifs après, faire un blame pour savoir à  quel moment / quelle version tu as modifié telle ligne de ton code... bref tout ce que GIT apporte.

    Utiliser GIT n'a pas forcément à  voir avec le travail en équipe, il est tout aussi utile pour du travail en solo. Tu serais sous GIT tu aurais un moyen très simple de comparer tes 2 codes, rebasculer sur l'un ou l'autre et rajouter des logs sur chacune des 2 versions pour comparer les résultats au runtime.
    Alors que faire une sauvegarde de ton projet, c'est toujours bien plus long et contraignant car tu dois garder tout plein de sauvegardes, tu n'as pas de date/message de commit/browser d'historique de code, ça prend du temps et surtout de l'espace (si ton projet fait 5Mo, ça veut dire que tu as 100Mo dès que tu as 20 sauvegardes de ton code ?! Alors que GIT ne garde que les diff et du coup le repo montera plutôt à  8Mo qu'à  100Mo...) et en plus de ça du coup vu le temps que ça prend de faire une copie/sauvegarde à  chaque fois, tu en fais beaucoup moins souvent que tu ne ferais un commit GIT (perso je préfère faire plein de micro-commits que d'attendre la fin de la journée de travail pour faire un gros commit qui contient plein (trop) de choses, ça permet de découper plus finement les évolutions et de rendre la bisection bien plus efficace en cas de recherche de bug)
  • AliGatorAliGator Membre, Modérateur

    Bah je suis passé de ça (exemple repris sur un Controller d'Offre)

    - (NSData *)searchOfferKeyword {

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@%@", @http://www.monsite.org/chercherOffres.php]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        NSString *requestFields = @"";
        requestFields = [requestFields stringByAppendingFormat:@nomTable=%@&;", nom_table];
        requestFields = [requestFields stringByAppendingFormat:@limite=%d&, limite];
        requestFields = [requestFields stringByAppendingFormat:@rang=%d&, rang];
        
        requestFields = [requestFields stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSData *requestData = [requestFields dataUsingEncoding:NSUTF8StringEncoding];
        request.HTTPBody = requestData;
        request.HTTPMethod = @POST;
    ...
    à  ce qui est posté dans les messages au dessus (Profil Controller)

    Bah du coup ça me paraà®t clair, ça confirme ce que je supposais, tu ne construis pas la même requête dans les 2 cas. Dans un cas quand tu construits ta requête, ta chaà®ne requestFields contient "nomTable=xxx&limite=y&rang=z", dans l'autre cas elle contient "pwd=x&admail=y" donc en effet les requêtes sont différentes, faut pas chercher.

    ---

    PS : Pas top la façon dont tu construits tes requestFields, au passage :

    1) Allouer des NSString à  chaque fois en demandant une nouvelle NSString avec "stringByAppendingFormat:" est un peu du gâchis, tu alloues une nouvelle chaà®ne à  chaque fois c'est un peu du gâchis. Si tu comptes construire une chaà®ne bout par bout, utilise plutôt NSMutableString, et travaille directement sur cette NSMutableString plutôt que recréer des nouvelles instances à  chaque fois.

    2) Tu appliques "stringByAddingPercentEscapesUsingEncoding:" sur toute ta chaà®ne, alors qu'il ne faut pas remplacer tes "=" et "&" de toute ta chaà®ne, il ne faut échapper que les valeurs. Ainsi si tu veux passer 2 paramètres a et b donc les valeurs sont "val&a" et "je dis b=1", il faut échapper le "&" de "val&a" et le "=" de "je dis b=1" mais pas le "&" ni le "=" de "a=val%26a&b=je%20dis%20b%3D1".
    En bref, dans ton cas il ne faut échapper que les variables nom_table, limite et rang, pas toute la chaà®ne

    3) [NSString stringWithFormat:@%@", str] est inutile et du gâchis (je suis étonné que tu n'aies pas un warning, d'ailleurs). Pas la peine de passer par un format pour mettre une chaà®ne qui est directement un litéral. Autant directement utiliser la chaà®ne litérale str et enlever complètement ton stringWithFormat qui ne sert strictement à  rien.
  • L'argument du travail en solo je l'ai cité, puisque c'est ce que m'a dit le collègue quand je lui ai demandé si lui utilisais Git.


     


    Je t'avoue que Git je ne connais quasiment pas (même si je vais devoir m'y mettre pour les projets scolaires à  rendre très prochainement).


     


    Peut être du coup as tu un tutoriel simple (et si possible en français) sur comment utiliser Git ? Ca me serait très utile pour moi et mes camarades.


     


    J'ai précisé que les requêtes sont différentes, ce sont 2 controllers bien distincts qui pointent sur 2 pages différentes, mais vu que le principe est quasi similaire (je l'ai repris et adapté) j'ai copié collé celui la.


     


    J'ai bien pris note des 3 points que tu as évoqué


  • AliGatorAliGator Membre, Modérateur
    GIT fonctionne complètement en local (c'est un de ses gros avantages), pas besoin d'un serveur pour l'utiliser.

    D'ailleurs quand tu crées un nouveau projet Xcode, il te propose de créer un repo local GIT par défaut.

    Il y a plein de threads sur CocoaCafé où on parle déjà  de GIT et où on explique plein de trucs à  son sujet, donne des instructions pour démarrer avec GIT et tout, je te laisse faire une recherche.
  • AliGatorAliGator Membre, Modérateur
    Si tu compares 2 requêtes différentes, comment veux-tu être sûr que ce soit normal ou pas que celle qui te pose problème retourne "[]" ? Peut-être (sûrement) qu'elle retournait déjà  "[]" avant que tu ne modifies ton code. Il faut comparer ce qui est comparable, tu as sans doute une requête qui te retourne un JSON correspondant à  un tableau avec plein de données, et une autre requête dont la réponse se trouve être un tableau JSON vide. Donc ce que tu observes et bien logique vu la requête que tu fais.

    D'ailleurs, il suffit de refaire la requête avec "curl" en ligne de commande, ou avec "PostMan" ou tout autre plugin de Safari ou Chrome pour tester des requêtes GET et POST et voir leur résultat, donc tout ça en dehors de Xcode et d'ObjC, pour voir ce que ton serveur de retourne vraiment.
  • Ben77650Ben77650 Membre
    mai 2014 modifié #26

    Pourtant je t'assure que quand la requête du profil était faite en synchrone, elle me renvoyais un tableau de valeurs donc je vois vraiment pas le probleme


     


    Et je veut bien les liens vers les sujets traitant de Git stp :D


  • AliGatorAliGator Membre, Modérateur
    mai 2014 modifié #27
    Ben bah fait une recherche (j'ai pas le temps de la faire pour toi là  je suis sous l'eau avec CP, mais bon t'es un grand garçon tu peux le faire tout seul)
  • AliGatorAliGator Membre, Modérateur
    T'as qu'à  tester ta requete avec la commande "curl" ou avec un outil comme PostMan et voir ce qu'elle te retourne, tu seras fixé de savoir si c'est ton code ou tes headers/ta requête qui sont pas bons.


  • Ben bah fait une recherche (j'ai pas le temps de la faire pour toi là  je suis sous l'eau avec CP, mais bon t'es un grand garçon tu peux le faire tout seul)




     


    J'ai parcouru et regarder la liste des sujets, et ça m'a pas franchement aider à  trouver mon bonheur ^^

  • samirsamir Membre

    Hello,


     


    http://pcottle.github.io/learnGitBranching/


    https://try.github.io/levels/1/challenges/1


    https://www.codeschool.com/courses/try-git


     


    Tu peux travailler aussi avec cet outil pour te faciliter la vie : http://www.sourcetreeapp.com/ 


     


    et y a un super livre mais j'ai oublié le titre :).


  • Merci et SourceTree j'ai utilisé en début d'année pour le projet iOS donc je connais un peu


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