Swift Package


El dilema de las dependencias rotas

Cuando trabajas con Swift Package Manager (SPM), eventualmente te encontrarás con un error de compilación que parece no tener sentido. Has intentado compilar varias veces, has reiniciado Xcode, pero el error persiste. La solución muchas veces está en limpiar correctamente las cachés y artefactos de SPM, pero ¿qué comando usar?

Existen múltiples formas de “limpiar” en SPM, cada una con un propósito específico. Usar el comando equivocado puede no resolver tu problema o, peor aún, forzarte a descargar gigabytes de dependencias nuevamente.

Los cuatro caminos para limpiar

SPM ofrece tres comandos oficiales más una alternativa manual. Cada uno afecta diferentes partes del sistema:

Comando Elimina .build local Elimina Package.resolved Elimina caché global
swift package clean No (solo binarios compilados) No No
swift package reset Sí (completo) No
swift package purge-cache No No
rm -rf .build Sí (completo) No No

Swift package clean

swift package clean

Qué hace:
Elimina únicamente los binarios compilados finales dentro de la carpeta .build, pero mantiene dependencias descargadas y archivos intermedios.

Cuándo usarlo:

  • Después de cambiar configuraciones de compilación
  • Para forzar una recompilación completa sin re-descargar dependencias
  • Cuando los binarios están corruptos pero las fuentes están bien

No descarga dependencias nuevamente ni resuelve problemas de caché de paquetes.

Swift package reset

swift package reset

Qué hace:
Elimina completamente la carpeta .build (incluyendo dependencias descargadas) y el archivo Package.resolved.

Cuándo usarlo:

  • Cuando hay conflictos en las versiones de dependencias
  • Después de cambios importantes en Package.swift
  • Para resolver errores de “dependencia no encontrada”
  • Cuando Package.resolved está desactualizado o corrupto

La próxima compilación descargará y resolverá todas las dependencias desde cero. Esto puede tardar varios minutos dependiendo de la cantidad de paquetes.

Swift package purge-cache

swift package purge-cache

Disponible desde Swift 5.7 en adelante.

Qué hace:
Elimina la caché global de paquetes ubicada en:

~/Library/Caches/org.swift.swiftpm/

Esta caché contiene repositorios clonados y artefactos binarios compartidos entre todos tus proyectos.

Cuándo usarlo:

  • Cuando múltiples proyectos tienen el mismo problema
  • Después de actualizar Xcode o herramientas de Swift
  • Para liberar espacio en disco (puede ocupar varios GB)
  • Cuando sospechas que la caché global está corrupta

Todos tus proyectos tendrán que re-descargar dependencias comunes.

rm -rf .build

rm -rf .build

Qué hace:
Elimina manualmente la carpeta .build completa, similar a reset pero sin tocar Package.resolved. Es menos agresivo que reset porque no re-resuelve dependencias.

Cuándo usarlo:

  • Para limpiar artefactos de compilación manteniendo la resolución de versiones
  • En scripts de CI/CD donde quieres control total
  • Cuando swift package reset no está disponible

Preserva Package.resolved, lo que significa que las versiones de dependencias no se re-resolverán.

Estrategia de resolución de problemas

Nivel 1: Limpieza ligera

swift package clean

Prueba primero lo menos invasivo. Resuelve el 30% de los problemas.

Nivel 2: Reset completo del proyecto

swift package reset

Si el nivel 1 falla. Resuelve el 60% de los problemas restantes.

Nivel 3: Purgar caché global

swift package purge-cache
swift package reset

Para problemas persistentes o que afectan múltiples proyectos.

Nivel 4: Nuclear

rm -rf .build
rm Package.resolved
swift package purge-cache

Última opción. Borrón y cuenta nueva total.

Casos de uso reales

Escenario 1: Error después de actualizar Xcode

swift package purge-cache
swift package reset

Las herramientas de compilación cambiaron y la caché puede tener artefactos incompatibles.

Escenario 2: Conflicto de versiones de dependencias

swift package reset

Necesitas re-resolver todas las dependencias con las nuevas restricciones.

Escenario 3: Espacio en disco lleno

swift package purge-cache

La caché global puede crecer hasta varios GB sin que lo notes.

Escenario 4: CI/CD builds

rm -rf .build

En entornos de integración continua, quieres builds limpios pero reproducibles con Package.resolved versionado.

Entendiendo los componentes

.build (local)

  • Artefactos de compilación del proyecto actual
  • Dependencias descargadas específicas del proyecto
  • Archivos intermedios de compilación

Package.resolved

  • “Lockfile” que fija versiones exactas de dependencias
  • Garantiza builds reproducibles
  • Debe versionarse en Git para proyectos compartidos

Caché global

  • Compartida entre todos tus proyectos Swift
  • Contiene clones de repositorios de dependencias
  • Artefactos binarios pre-compilados
  • Puede alcanzar varios GB con el tiempo

Mejores prácticas

Versiona Package.resolved en Git para garantizar que todo el equipo use las mismas versiones

Usa reset después de cambios en Package.swift para asegurar una resolución limpia

Purga la caché periódicamente si trabajas con muchos proyectos

En CI/CD, mantén Package.resolved pero elimina .build para builds limpios

No ignores .build en .gitignore - ya está ignorado por defecto

No borres Package.resolved a menos que realmente necesites re-resolver versiones

Conclusión

Entender la diferencia entre estos comandos te ahorra tiempo y frustración. No todos los problemas de compilación necesitan una limpieza nuclear:

  • clean → Solo binarios compilados
  • reset → Proyecto completo + Package.resolved
  • purge-cache → Caché global compartida
  • rm -rf → Control manual quirúrgico

La próxima vez que SPM te muestre un error extraño, ya sabes exactamente qué herramienta usar.

Keep coding, keep running 🏃‍♂️