Revue de code Swift : que vérifier et comment donner du feedback
La revue de code n'est pas seulement une procédure formelle, mais un outil puissant pour améliorer la qualité du code et la croissance professionnelle de l'équipe. Pour les développeurs iOS/macOS en Swift, une revue bien menée permet d'éviter les bugs, d'améliorer l'architecture et de maintenir un style de code cohérent. Dans cet article, nous allons voir à quoi faire attention lors d'une revue de code de projets Swift, et comment donner un feedback utile sans démotiver.
1. Architecture et séparation des responsabilités
La première chose à évaluer lors d'une revue est de savoir à quel point le code correspond à l'architecture choisie (MVC, MVVM, VIPER, SwiftUI + Combine). Une mauvaise architecture conduit à des « God-objets » et à une maintenance complexe.
Que vérifier :
- Le ViewController ne mélange-t-il pas la logique métier et le code UI ?
- La logique réseau est-elle extraite dans des services séparés (NetworkService) ?
- Utilise-t-on des protocoles pour l'abstraction des dépendances ?
- Une classe n'a-t-elle pas trop de responsabilités ?
// ❌ Mauvais : ViewController connaît URLSession et le parsing JSONclass UserViewController: UIViewController { func fetchUser() { URLSession.shared.dataTask(with: URL(string: "https://api.example.com/user")!) { data, _, _ in let user = try? JSONDecoder().decode(User.self, from: data!) DispatchQueue.main.async { self.updateUI(with: user) } }.resume() }}
// ✅ Bon : la logique est extraite dans un serviceprotocol UserServiceProtocol { func fetchUser(completion: @escaping (Result<User, Error>) -> Void)}
class UserViewModel { private let userService: UserServiceProtocol init(userService: UserServiceProtocol) { self.userService = userService } func loadUser() { userService.fetchUser { [weak self] result in // traitement du résultat } }}Conseil pour le feedback : Au lieu de « Cette classe est trop grosse », écrivez : « Je vois que UserViewController gère à la fois les requêtes réseau et l'UI. Peut-être faudrait-il extraire la requête dans un service séparé, comme nous en avons discuté à la rétro ? Cela faciliterait les tests ».
2. Sécurité mémoire et gestion du cycle de vie
Swift est un langage avec comptage automatique de références (ARC), mais cela ne dispense pas le développeur de se soucier des cycles de références fortes. Les erreurs dans ce domaine sont une cause fréquente de fuites mémoire dans les applications iOS.
Que vérifier :
- Utilise-t-on
[weak self]ou[unowned self]dans les closures, surtout avec async/await et Combine ? - Ne crée-t-on pas une référence cyclique entre le délégué et son propriétaire ?
- Les ressources sont-elles correctement libérées (observateurs, timers) ?
// ❌ Fuite potentielle : référence forte à self dans la closureclass LocationManager { var onLocationUpdate: ((CLLocation) -> Void)? func startUpdating() { someAsyncAPI { location in self.onLocationUpdate?(location) // self est capturé fortement } }}
// ✅ Corrigé avec [weak self]class LocationManager { var onLocationUpdate: ((CLLocation) -> Void)? func startUpdating() { someAsyncAPI { [weak self] location in guard let self = self else { return } self.onLocationUpdate?(location) } }}Conseil pour le feedback : Ne mentionnez pas seulement le problème, mais aussi ses conséquences : « Il pourrait y avoir une fuite mémoire ici si LocationManager vit plus longtemps que nécessaire. Ajoutons [weak self] pour briser le cycle ».
3. Gestion des erreurs et optionnalité
Swift est un langage fortement typé avec un système Optional puissant. Une mauvaise gestion des valeurs optionnelles est l'une des