Code Review en Swift: qué revisar y cómo dar retroalimentación en la práctica
\n\nEl code review no es solo una formalidad, sino una herramienta poderosa para mejorar la calidad del código, difundir el conocimiento dentro del equipo y prevenir errores. Sin embargo, si se aborda de manera formal o, por el contrario, demasiado agresiva, puede causar más daño que beneficio. En este artículo, analizaremos en qué aspectos específicos hay que fijarse al revisar código Swift para iOS y macOS, y cómo formular la retroalimentación para que sea útil y no hiera a los colegas.
\n\n1. Arquitectura y diseño: mirando la raíz
\n\nAntes de sumergirse en los detalles de implementación, evalúe la arquitectura general de la solución. Un buen código no es solo sintaxis, sino también estructura.
\n\n- \n
- Principio de Responsabilidad Única (SRP): ¿La clase/función intenta hacer demasiado? Por ejemplo, ¿el ViewController mezcla lógica de negocio y solicitudes de red? \n
- MVVM / MVC / VIPER: ¿El código se ajusta al patrón elegido? Si el proyecto usa MVVM, entonces la ViewModel no debería importar
UIKit. \n - Gestión de dependencias: ¿Se utiliza inyección de dependencias (DI) o los objetos se crean internamente? Las dependencias rígidas dificultan las pruebas. \n
- Gestión de memoria: ¿Hay fugas? Verifique los cierres
@escaping, las referencias fuertes aselfy las posibles capturas cíclicas. \n
// Malo: referencia fuerte a self en un cierre\nclass NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n URLSession.shared.dataTask(with: URL(string: "https://api.example.com")!) { data, _, _ in\n self.onComplete?() // ¡Fuga! El cierre mantiene una referencia fuerte a self\n }.resume()\n }\n}\n\n// Bueno: usamos [weak self]\nclass NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n URLSession.shared.dataTask(with: URL(string: "https://api.example.com")!) { [weak self] data, _, _ in\n DispatchQueue.main.async {\n self?.onComplete?()\n }\n }.resume()\n }\n}\n\n2. Seguridad de tipos y opcionalidad: usando el poder de Swift
\n\nSwift es un lenguaje con tipado fuerte, y el code review debe reflejar esto. Evite el "código ObjC envuelto en Swift".
\n\n- \n
- Force unwrapping: ¿Hay
!donde se pueda evitar? Useguard letoif let. \n - Enumeraciones (Enums): ¿Se usan en lugar de constantes de cadena? Por ejemplo, para estados de respuesta o tipos de error. \n
- Result type: ¿Se maneja el error mediante
Result<Success, Failure>en lugar de devolver un valor opcional y un error por separado? \n - Generic: ¿Qué tan apropiado es el uso de genéricos? A veces complican el código innecesariamente. \n
// Malo: force unwrap y constantes de cadena\nfunc getUser(id: String!) -> User? {\n if id == "admin" {\n return User(name: "Admin")\n }\n return nil\n}\n\n// Bueno: enum y extracción segura\nenum UserType: String {\n case admin\n case regular\n}\n\nfunc getUser(id: String?) -> User? {\n guard let userId = id, let userType = UserType(rawValue: userId) else {\n return nil\n }\n // ... lógica\n return User(name: userType.rawValue)\n}\n\n3. Rendimiento y trabajo con UI: cuidando la batería y los FPS
\n\nPara aplicaciones iOS/macOS, la fluidez de las animaciones y la eficiencia energética son críticas. Preste atención a:
\n\n- \n
- Main Thread: Todas las actualizaciones de la UI deben ocurrir en el hilo principal. Verifique que no haya llamadas a
UIViewoNSViewdesde colas en segundo plano. \n - Cálculos pesados: ¿No se están realizando operaciones complejas en el hilo principal? Considere moverlas a colas en segundo plano. \n