Refactorización de código legacy en Swift: guía paso a paso para iOS/macOS

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: Por qué el código Swift heredado necesita refactorización

Trabajar con código heredado es una parte inevitable de la vida de un desarrollador de iOS/macOS. Incluso si un proyecto fue escrito originalmente en Swift, con el tiempo acumula deuda técnica: patrones obsoletos, falta de pruebas, arquitectura monolítica y mezcla de Swift con Objective-C. Refactorizar dicho código no solo mejora la legibilidad, sino que reduce los costos de mantenimiento, acelera la incorporación de nuevas funciones y disminuye la cantidad de errores.

En este artículo, cubriremos técnicas específicas para refactorizar código Swift heredado: desde eliminar el force unwrapping hasta migrar de MVC a MVVM. Todos los ejemplos se pueden aplicar tanto a proyectos de iOS como de macOS.



1. Evaluación y preparación: por dónde empezar la refactorización

Antes de cambiar el código, es importante comprender su estado actual. Utiliza las herramientas y métricas integradas de Xcode.



1.1. Análisis de advertencias y errores

Abre el proyecto en Xcode y ve al Report Navigator (Cmd+9). Presta atención a:

  • Advertencias amarillas — APIs obsoletas, variables no utilizadas.
  • Errores rojos — errores de sintaxis que pueden ser resultado de una migración incompleta de Swift.
  • SwiftLint/SwiftFormat — conecta un linter para detectar automáticamente violaciones de estilo de código.


1.2. Búsqueda de "banderas rojas" en el código

Escanea el proyecto usando la búsqueda (Cmd+Shift+F) para los siguientes patrones:

  • ! — force unwrapping (valores opcionales que bloquean la app).
  • as! — force casting (conversión de tipo sin verificación).
  • try! — ignorar errores.
  • NSObject — heredar de NSObject sin necesidad (Swift puro no lo requiere).
  • #selector — selectores de cadena, que es mejor reemplazar con #selector con tipo.


// Malo (heredado)let name = user.name!  // force unwrap — crash en nil

// Bueno (refactorización)guard let name = user.name else { return}


1.3. Escribir pruebas antes de los cambios

La refactorización sin pruebas es riesgosa. Si no hay pruebas, comienza agregándolas para los módulos críticos. Usa XCTest para pruebas unitarias y XCUITest para UI.

Ejemplo de una prueba simple para una función heredada:

class LegacyCalculatorTests: XCTestCase {    func testCalculateTotal() {        let calculator = LegacyCalculator()        let result = calculator.calculateTotal(items: [10, 20, 30])        XCTAssertEqual(result, 60)    }}


2. Técnicas básicas para refactorizar código Swift

Pasemos a los pasos prácticos que se pueden aplicar ahora mismo.



2.1. Reemplazar force unwrapping con patrones seguros

El problema más común en el código heredado es el uso generalizado de !. Reemplázalos con guard let, if let o ?? (nil-coalescing).

// Antes de la refactorizaciónfunc getUserName() -> String {    return user.name!}

// Después de la refactorizaciónfunc getUserName() -> String { return user.name ?? "Unknown"}


2.2. Eliminar el Massive View Controller (MVC → MVVM)

Los proyectos heredados a menudo sufren de controladores "gordos". Extrae la lógica de negocio en servicios separados o ViewModel.

// ViewController heredado (fragmento)class ProfileViewController: UIViewController {    @IBOutlet weak var nameLabel: UILabel!        override func viewDidLoad() {        super.viewDidLoad()        // Lógica de negocio directamente en el controlador        let user = DataManager.shared.fetchUser()        nameLabel.text = user.name?.capitalized    }}

// Después de la refactorizaciónclass ProfileViewModel { private let userService: UserService var userName: String { return userService.currentUs

Blogs

Book Recommendations