• 12 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 24/05/2022

Récupérez la citation avec une requête POST

C'est parti ! Accrochez vos ceintures ! Nous allons lancer notre première requête !

Créez le fichier

Les appels réseaux concernent la logique de l'application, et ont donc lieu dans le modèle. On va donc rajouter un fichier  QuoteService.swift  dans le modèle.

Dans ce fichier, créez la classe  QuoteService  , vide pour l'instant.

Créez la requête

Souvenez-vous, pour faire un appel réseau, il nous faut une instance  URLSession  qui lance une  URLSessionTask  , cette dernière étant initialisée avec une  URLRequest  . Nous allons commencer par créer cette requête.

Pour cela, nous avons besoin de l'URL. Comme on l'a vu dans le chapitre avec Postman, l'URL, la voici : http://api.forismatic.com/api/1.0/ . Je vous propose de la rajouter dans la classe sous la forme d'une constante de classe privée :

private static let quoteUrl = URL(string: "https://api.forismatic.com/api/1.0/")!

Maintenant, nous allons créer une fonction statique que nous allons appeler simplement  getQuote  , et à l'intérieur de laquelle nous allons créer notre requête :

static func getQuote() {
   var request = URLRequest(url: quoteUrl)
   request.httpMethod = "POST"
}

J'initialise une instance de  URLRequest  en lui passant notre URL en paramètre. Ensuite, je précise la méthode HTTP choisie (en l'occurrence  POST  ) avec la propriété  httpMethod  de  URLRequest  .

Par ailleurs, nous avons besoin de passer des paramètres dans cette requête. Nous allons les rajouter avec la propriété  body  de  URLRequest  :

let body = "method=getQuote&lang=en&format=json"
request.httpBody = body.data(using: .utf8)

J'écris les paramètres sous la forme d'une chaîne de caractères. Vous reconnaissez les paramètres que l'on a utilisés précédemment avec Postman. Ensuite, j'utilise la méthode  data(using:)  du type  String  , qui permet de convertir une chaîne de caractères vers le format  Data  . Et je précise l'encodage de mon choix, en l'occurrence  utf8  , le plus courant dans l'univers du développement.

Et voilà, notre requête est créée, nous avons précisé son URL, sa méthode et ses paramètres. On va pouvoir créer et lancer notre tâche !

Lancez la tâche

On l'a vu au chapitre précédent, pour lancer une tâche, il faut une instance  d'URLSession  . Pour cela, nous allons créer une instance  d'URLSession  avec une configuration par défaut :

let session = URLSession(configuration: .default)

Ensuite, nous allons créer une tâche, et plus précisément une instance de  URLSessionDataTask  :

let task = session.dataTask(with: request) { (data, response, error) in
}

Plusieurs choses ici :

  • On crée une tâche qu'on stocke dans la constante task.

  • Pour cela, on utilise la méthode dataTask de URLSession.

    • Elle prend en paramètre notre requête request de type URLRequest.

    • Elle admet un deuxième paramètre : une fermeture. C'est dans cette fermeture que nous allons gérer la réponse de l'appel. Il admet 3 paramètres, comme on l'a vu au chapitre précédent : data de type Data?, response de type URLResponse? et error de type Error?.

Notre tâche est maintenant créée et pour lancer l'appel, il ne nous reste plus qu'à écrire :

task.resume()

Et voilà ! Votre appel va être lancé !

Gérez la réponse

Lorsque l'on gère la réponse, nous allons vérifier qu'elle contient bien les données qui nous intéressent, et que nous n'avons pas d'erreur. Nous allons donc commencer par écrire ceci :

let task = session.dataTask(with: request) { (data, response, error) in
   guard let data = data, error == nil else {
      // Si on devait gérer l’erreur, ce serait ici
      return
   }}

Attends attends ! Guard ? C’est quoi ça, guard ? 😲

Je sais, c’est un mot nouveau mais pas de panique, c’est juste une autre façon de gérer les erreurs, plus propre que le if. Nous rentrerons plus en détail dans la prochaine partie. Sachez seulement que si nous n’avons pas d’erreur, nous ne rentrerons pas dans la portée du guard et nous continuerons notre programme tranquillement.

Ensuite, nous allons contrôler que le  status code  de la réponse est bien à 200 :

let task = session.dataTask(with: request) { (data, response, error) in
   guard let data = data, error == nil else {
      // gérer l’erreur ici
      return
   }

 
      guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
         // gérer ici l’erreur de status code
         return
      }
   }
}   

On vérifie d'abord que la réponse est bien du type  HTTPURLResponse  , et ensuite que le code vaut bien 200.

Décodez les données JSON

Avec les vérifications que nous avons faites, nous savons maintenant que la requête renvoie bien des données, et qu'il n'y a pas d'erreur. Seulement, souvenez-vous, nous avons demandé à ce que les données soient au format JSON :

let body = "method=getQuote&lang=en&format=json" // <= ICI

Or, nous ne savons pas manipuler ce format en Swift. En Swift, on manipule des dictionnaires, des tableaux, des objets, mais pas des JSON !

Heureusement, il existe une classe qui va nous permettre de faire la conversion depuis le format JSON vers un dictionnaire Swift classique. Elle s'appelle :  JSONDecoder  . Et elle a une méthode  decode  qui renvoie un dictionnaire. Voici comment on l'utilise :

guard let responseJSON = try? JSONDecoder().decode([String: String].self, from: data) else {
   // gérer l’erreur de décodage
   return
}
guard let text = responseJSON["quoteText"],
   let author = responseJSON["quoteAuthor"] else {
   // gérer l’erreur ici
   return
}

Woooooh...

Oui je sais, il y a pas mal de choses ici, mais à part la première ligne, rien de vraiment compliqué :

  • Ligne 1 : On utilise la méthode decode de  JSONDecoder  , qui prend en paramètre deux choses :

    • le type attendu des données que l'on va recevoir, ici on s'attend à recevoir un dictionnaire qui a comme type  String  pour la clé et pour la valeur. Le  .self  permet de faire référence au type ;

    • les  data  reçues en réponse à l'appel réseau, et d'éventuelles options que nous laissons vides.

  • Lignes 6 et 7 : Comme on a déjà vu à quoi ressemblaient les données reçues grâce à Postman, on sait que la citation est stockée avec la clé quoteText, et l'auteur avec la clé quoteAuthor. On récupère du coup simplement les valeurs correspondantes.

Pour être encore plus efficace, je vous propose de gérer toutes les conditions en une fois, comme ceci :

guard let responseJSON = try? JSONDecoder().decode([String: String].self, from: data), let text = responseJSON["quoteText"],
   let author = responseJSON["quoteAuthor"] else {
   // gérer l’erreur de décodage
   return
}

Ensuite, vous pouvez faire des prints sur les variables text et author, et vous devriez voir les citations s'afficher dans votre console en appuyant sur le bouton New Quote dans votre simulateur !

Et voilà ! Dans le prochain chap...

Hop hop hop ! Tu ne vas pas t'en sortir comme ça ! Tu n’aurais pas oublié quelque chose ?

Comment ça ?

C'est quoi ça : try? ?!

Aaaah ! Certes... Bon, pour la faire courte, certaines fonctions comme la fonction decode peuvent planter et dans ce cas, on dit qu'on essaie de lancer la fonction avec try?. Je ne vous en dis pas plus pour le moment pour qu'on ne s'éparpille pas. Mais c'est le sujet de la dernière partie de ce cours. Alors, heureux ?

Hmmm.... On va dire oui  !

En résumé

  • Pour récupérer des données JSON en précisant des paramètres, vous devez créer une requête HTTP  POST  .

  • Pour créer une requête HTTP  POST  :

    • Configurez la classe  URLRequest  en précisant le type de méthode HTTP et les paramètres dans le body.

    • Lancez la tâche en utilisant la classe  URLSession  et sa sous-classe  URLSessionDataTask  . 

    • N’oubliez pas de faire un  task.resume()  en lançant la tâche, sinon la requête ne partira jamais !

    • Décodez les données JSON pour extraire les informations dont vous avez besoin.

Vous savez désormais créer une requête POST. Dans le prochain chapitre, nous allons mettre en place le téléchargement de l'image aléatoire associée à la citation !

Exemple de certificat de réussite
Exemple de certificat de réussite