#Couche réseau

Maintenant que nous savons comment faire un appel réseau simple nous allons mieux agencer notre code pour une réutilisation plus simple.

Voilà ce que nous visons :

#UnsplashAPI.swift

Ce fichier doit contenir la logique spécifique à l’API Unsplash, nous y retrouverons le système d’authentification à l’API, la construction des URLs en fonction des besoins.

Ce fichier ne contient pas de code SwiftUI.

#🔧 Exercice 1 ~30min

Dans ce fichier construisez les fonctions suivantes dans une struct UnsplashAPI:

  • unsplashApiBaseUrl permettra de construire l’URL de base de l’API Unsplash
    // Construit un objet URLComponents avec la base de l'API Unsplash
    // Et un query item "client_id" avec la clé d'API retrouvé depuis PListManager
    func unsplashApiBaseUrl() -> URLComponents {}
  • FeedURL permettra de construire l’URL complète pour récupérer les images de la route /photos en se basant sur unsplashApiBaseUrl et en ajoutant les query items nécessaires
    // Par défaut orderBy = "popular" et perPage = 10 -> Lisez la documentation de l'API pour comprendre les paramètres, vous pouvez aussi en ajouter d'autres si vous le souhaitez
    func feedUrl(orderBy: String = "popular", perPage: Int = 10) -> URL? {}

Il faudra également créer des variables pour stocker des éléments de l’URL de base de l’API Unsplash, comme le scheme, le host, etc.

#FeedState

C’est le fichier qui contiendra notre Source de vérité, c’est à dire les données que nous allons afficher dans notre application.

FeedState s’occupera de gérer l’état de nos vues et de faire les appels réseau nécessaires pour récupérer les données. Ce sera donc un ObservableObject qui contiendra un ou plusieurs @Published qui seront notre source de vérité.

Notre fichier FeedState sera alors déclaré comme ceci dans nos vues :

@StateObject var feedState = FeedState()

Cela permet d’indiquer au framework que notre vue dépend de cet objet et qu’il doit être conservé en mémoire tant que la vue est affichée.

#Ressources

#🔧 Exercice 2 ~1h

Créez un fichier FeedState.swift et créez une classe FeedState qui respecte le protocole ObservableObject.

Voici ce que la classe doit contenir :

@Published var homeFeed: [UnsplashPhoto]?

// Fetch home feed doit utiliser la fonction feedUrl de UnsplashAPI
// Puis assigner le résultat de l'appel réseau à la variable homeFeed
func fetchHomeFeed() async {} 

Pour une structure encore plus propre nous aurions pu créer un UnsplashPhotoRepository qui aurait contenu toutes nos fonctions d’appel réseau. Mais pour cet exercice nous allons nous contenter de mettre tout dans FeedState.

#FeedState dans la vue

Maintenant que nous avons notre FeedState nous allons l’utiliser dans notre vue.

#🔧 Exercice 3 ~20min

  1. Créez une variable feedState dans votre vue, cela doit être un @StateObject
  2. Assigner lui une instance de FeedState
  3. Appelez la fonction fetchHomeFeed de votre FeedState dans l’action de votre bouton LoadData
  4. Affichez les images de votre FeedState dans votre grille, en remplaçant le paramètre de votre ForEach par feedState.homeFeed

Gérer le fait que homeFeed soit optionnel, et que la grille ne doit pas s’afficher tant que homeFeed est nil.

Votre grille doit maintenant fonctionner avec votre FeedState et donc avec l’appel réseau.

Cette nouvelle architecture va nous permettre d’ajouter bien plus facilement des requêtes à faire à l’API, mais aussi de conserver une instance des données en mémoire pour les réutiliser plus tard, et éviter des appels inutiles.

#🔧 Exercice 4 ~40min

Gérer l’UI lors du chargement ou de l’absence de données :

  • Utilisez le modifier .redacted(reason: .placeholder) sur votre grille pour afficher un placeholder pendant le chargement des données.
  • Il faudra créer une grille de substitution de 12 éléments pour que l’effet fonctionne ici.

Le résultat doit être le suivant :

Notre exercice ne s’y prête pas vraiment, mais sachez que vous pouvez utiliser .redacted(reason: .placeholder) sur n’importe quelle vue, et SwiftUI créera automatiquement un placeholder pour vous.


Bonus : Si vous êtes chaud vous pouvez aussi remplacer le progressView par un RoundedRectangle de la couleur fournie par l’API Unsplash permettant d’avoir un effet de fluidité entre la couleur et l’image qui s’affichera ensuite.