Swift Package Manager en 2026: Creación, Publicación y Preguntas de Entrevista

Guía completa de Swift Package Manager. Aprende a crear paquetes Swift, gestionar dependencias, publicar bibliotecas y prepararte para entrevistas iOS.

Swift Package Manager en 2026: Creación, Publicación y Preguntas de Entrevista

Swift Package Manager (SPM) gestiona la distribución de dependencias y paquetes para proyectos Swift. A diferencia de CocoaPods o Carthage, SPM se integra directamente en Xcode y la cadena de herramientas Swift, sin requerir instalación externa. Swift 6.2 y 6.3 introdujeron configuraciones de seguridad de memoria estrictas, aislamiento de actores por defecto y el nuevo sistema Swift Build, convirtiendo a SPM en la opción definitiva para el desarrollo iOS moderno.

Funcionamiento de SPM

Swift Package Manager resuelve dependencias, descarga código fuente, compila módulos y los enlaza en el binario final. Un único archivo manifest Package.swift define todo: dependencias, targets, productos y configuraciones de compilación.

Estructura y Sintaxis del Manifest Package.swift

Cada paquete Swift comienza con un archivo Package.swift en la raíz del repositorio. Este manifest usa código Swift para declarar la estructura del paquete, las dependencias y la configuración de compilación.

Package.swiftswift
import PackageDescription

let package = Package(
    name: "NetworkKit",
    platforms: [
        .iOS(.v15),
        .macOS(.v12)
    ],
    products: [
        .library(
            name: "NetworkKit",
            targets: ["NetworkKit"]
        )
    ],
    dependencies: [
        .package(
            url: "https://github.com/Alamofire/Alamofire.git",
            from: "5.9.0"
        )
    ],
    targets: [
        .target(
            name: "NetworkKit",
            dependencies: ["Alamofire"]
        ),
        .testTarget(
            name: "NetworkKitTests",
            dependencies: ["NetworkKit"]
        )
    ]
)

El array platforms especifica los targets de despliegue mínimos. La sección products define lo que otros paquetes pueden importar. La sección targets lista las unidades de compilación con sus dependencias respectivas.

Crear un Paquete Swift desde la Línea de Comandos

El comando swift package init genera un nuevo paquete con la estructura de directorios estándar. La bandera --type determina si el paquete produce una biblioteca o un ejecutable.

bash
# Crear un paquete de biblioteca
mkdir NetworkKit && cd NetworkKit
swift package init --type=library

# Estructura generada:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │   └── NetworkKit/
# │       └── NetworkKit.swift
# └── Tests/
#     └── NetworkKitTests/
#         └── NetworkKitTests.swift

Ejecutar swift build compila el paquete. Ejecutar swift test lanza la suite de pruebas. Ambos comandos usan la configuración de Package.swift sin configuración adicional.

Especificación de Versiones y Resolución de Dependencias

SPM soporta tres estrategias de especificación de versión: versión exacta, rango de versiones y referencia de rama o commit. La elección afecta la reproducibilidad y flexibilidad.

Package.swiftswift
dependencies: [
    // Versionado semántico: 5.9.0 hasta la próxima versión mayor
    .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
    
    // Versión exacta: bloqueada en 5.9.1
    .package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
    
    // Rango de versiones: 5.8.0 a 5.9.9
    .package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
    
    // Referencia de rama: para desarrollo
    .package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
    
    // Referencia de commit: fijada a un commit específico
    .package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]

El archivo Package.resolved registra las versiones exactas resueltas durante la resolución de dependencias. Este archivo debe incluirse en el control de versiones para compilaciones reproducibles entre miembros del equipo y sistemas CI.

Dependencias de Rama en Producción

Las referencias de rama y commit eluden el versionado semántico. Usar branch: "main" en una aplicación en producción significa que cualquier push a main puede romper la compilación. Las referencias de rama deben reservarse para desarrollo activo contra características no publicadas.

Agregar Paquetes a un Proyecto Xcode

Xcode integra SPM a través del menú Archivo. Navegar a File, luego Add Package Dependencies. Ingresar la URL del repositorio, seleccionar la regla de versión y elegir qué targets deben enlazar la dependencia.

AppDelegate.swiftswift
import UIKit
import Alamofire // Disponible después de agregar vía Xcode

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        AF.request("https://api.example.com/health").response { response in
            print(response.result)
        }
        return true
    }
}

Xcode almacena las referencias de paquetes en el archivo .xcodeproj y las versiones resueltas en Package.resolved en la raíz del proyecto. La carpeta Derived Data almacena en caché los paquetes descargados.

Desarrollo Local con Dependencias de Ruta

Durante el desarrollo, apuntar a una ruta local en lugar de una URL remota permite iteración rápida sin publicar versiones intermedias. Esta técnica es adecuada para configuraciones monorepo y desarrollo de características.

Package.swift en el paquete consumidorswift
dependencies: [
    // Ruta local para desarrollo
    .package(path: "../NetworkKit"),
    
    // URL remota para release
    // .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]

Cambiar entre dependencias locales y remotas comentando la línea inactiva. Xcode y el CLI de Swift resuelven las dependencias de ruta relativas al paquete consumidor.

¿Listo para aprobar tus entrevistas de iOS?

Practica con nuestros simuladores interactivos, flashcards y tests técnicos.

Publicar un Paquete Swift en GitHub

La publicación requiere un repositorio Git con tags de versión semántica. SPM trata los tags de Git como versiones de release. El Swift Package Index indexa paquetes públicos automáticamente.

bash
# Inicializar repositorio y hacer push
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/NetworkKit.git
git push -u origin main

# Crear tag de versión
git tag 1.0.0
git push origin 1.0.0

# Otros paquetes ahora pueden depender de:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")

Seguir las convenciones de versionado semántico: incrementar la versión mayor para cambios incompatibles, menor para nuevas características y parche para correcciones de errores. SPM asume adherencia a estas reglas al resolver requisitos de versión from:.

Configuraciones de Paquetes Swift 6.2 y 6.3

Swift 6.2 introdujo configuración de modo de lenguaje por target y configuraciones de seguridad de memoria estrictas. Swift 6.3 agrega integración de Swift Build como sistema de compilación opcional.

Package.swift con características de Swift 6.2+swift
import PackageDescription

let package = Package(
    name: "SafeNetworkKit",
    platforms: [.iOS(.v17)],
    products: [
        .library(name: "SafeNetworkKit", targets: ["SafeNetworkKit"])
    ],
    targets: [
        .target(
            name: "SafeNetworkKit",
            swiftSettings: [
                // Habilitar modo Swift 6 solo para este target
                .swiftLanguageMode(.v6),
                // Habilitar verificación estricta de seguridad de memoria (SE-0458)
                .enableExperimentalFeature("StrictMemorySafety"),
                // Establecer aislamiento de actores por defecto (SE-0466)
                .enableExperimentalFeature("GlobalActorIsolation")
            ]
        )
    ]
)

La configuración swiftLanguageMode permite adopción gradual de características de Swift 6 en una base de código. Los targets pueden usar diferentes modos de lenguaje dentro del mismo paquete.

Generación de SBOM para Cumplimiento de Seguridad

SE-0509 agregó generación nativa de Software Bill of Materials en Swift 6.3. Los documentos SBOM listan todas las dependencias y sus versiones para auditoría de seguridad y cumplimiento regulatorio.

bash
# Generar SBOM en formato CycloneDX
swift build --sbom-spec cyclonedx

# Generar SBOM usando subcomando dedicado
swift package generate-sbom --format spdx

# La salida incluye:
# - Nombre y versión del paquete
# - Todas las dependencias transitivas
# - Información de licencias
# - URLs de repositorios fuente

Los entornos empresariales y contratos gubernamentales requieren cada vez más documentación SBOM. Los formatos CycloneDX y SPDX se integran con herramientas estándar de escaneo de vulnerabilidades.

Targets Binarios y Distribución de XCFramework

Los targets binarios permiten distribución de frameworks precompilados en lugar de código fuente. Los XCFrameworks agrupan binarios para múltiples plataformas y arquitecturas.

Package.swift con target binarioswift
import PackageDescription

let package = Package(
    name: "AnalyticsSDK",
    platforms: [.iOS(.v14)],
    products: [
        .library(name: "AnalyticsSDK", targets: ["AnalyticsSDK"])
    ],
    targets: [
        .binaryTarget(
            name: "AnalyticsSDK",
            url: "https://releases.example.com/AnalyticsSDK-2.0.0.xcframework.zip",
            checksum: "abc123def456..."
        )
    ]
)

// Generar checksum:
// swift package compute-checksum AnalyticsSDK-2.0.0.xcframework.zip

Los targets binarios reducen tiempos de compilación para consumidores y protegen implementaciones propietarias. El checksum garantiza la integridad de la descarga.

Preguntas de Entrevista Comunes sobre Swift Package Manager

Las entrevistas técnicas para posiciones iOS frecuentemente incluyen preguntas sobre SPM. Estas van desde uso básico hasta decisiones arquitectónicas.

P: ¿Cómo difiere SPM de CocoaPods y Carthage?

SPM se integra en Xcode y la cadena de herramientas Swift sin herramientas externas. CocoaPods usa un repositorio de especificaciones central y modifica la estructura del workspace de Xcode. Carthage compila frameworks en un paso separado sin integración con Xcode. SPM resuelve dependencias y compila en un único proceso unificado. La documentación de Apple sobre paquetes Swift cubre las herramientas oficiales.

P: ¿Qué sucede durante la resolución de dependencias?

SPM lee los manifests Package.swift recursivamente, construyendo un grafo de dependencias. Luego aplica restricciones de versión para encontrar versiones compatibles para todos los paquetes. El resolvedor escribe versiones exactas en Package.resolved. Los conflictos ocurren cuando dos paquetes requieren versiones incompatibles de una dependencia compartida.

P: ¿Cómo manejar un conflicto de dependencia en diamante?

Cuando los paquetes A y B dependen del paquete C con requisitos de versión incompatibles, la resolución de SPM falla. Las soluciones incluyen: actualizar un consumidor para soportar un rango de versiones más amplio, hacer fork del paquete restrictivo, o usar aliasing de módulo si el conflicto es entre diferentes paquetes con el mismo nombre de módulo.

swift
// Aliasing de módulo para conflictos de nombres
.target(
    name: "MyApp",
    dependencies: [
        .product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
    ]
)

P: ¿Cuándo usar un target binario en lugar de distribución de código fuente?

Los targets binarios son adecuados para SDKs propietarios donde la exposición del código fuente es inaceptable, grandes dependencias donde el tiempo de compilación afecta la productividad del desarrollador, y bibliotecas de vendor precompiladas. La distribución de código fuente sigue siendo preferible para proyectos de código abierto y bibliotecas internas donde depurar dentro de las dependencias agrega valor.

Migrar de CocoaPods a Swift Package Manager

La migración requiere reemplazar entradas del Podfile con referencias de paquetes SPM. No todos los CocoaPods tienen equivalentes SPM, por lo que se debe verificar disponibilidad en Swift Package Index antes de comenzar.

ruby
# Antes: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'
swift
// Después: Dependencias de paquetes en Xcode
// File > Add Package Dependencies para cada uno:
// https://github.com/Alamofire/Alamofire.git from 5.9.0
// https://github.com/SwiftyJSON/SwiftyJSON.git from 5.0.0
// https://github.com/onevcat/Kingfisher.git from 7.0.0

Eliminar el Podfile, Podfile.lock y el directorio Pods después de la migración. Ejecutar pod deintegrate para remover modificaciones del workspace de CocoaPods. Las declaraciones de import en archivos Swift permanecen sin cambios.

Mejores Prácticas de SPM para Aplicaciones en Producción

  • Fijar versiones mayores con from: para estabilidad mientras se reciben actualizaciones menores y parches
  • Incluir Package.resolved en el control de versiones para garantizar compilaciones reproducibles en el equipo
  • Usar paquetes locales durante desarrollo activo, cambiando a URLs remotas antes de hacer merge
  • Separar dependencias solo de prueba usando testTarget para evitar incluirlas en compilaciones de release
  • Documentar la versión mínima de herramientas Swift al inicio del manifest: // swift-tools-version: 5.10
  • Validar compilaciones de paquetes en CI antes de crear tags de release
Versión de Herramientas Swift

El comentario // swift-tools-version: debe aparecer en la primera línea de Package.swift. Determina qué versión de la API PackageDescription usa el manifest. Swift 6.0 agregó flexibilidad para permitir este comentario en líneas posteriores para encabezados de licencia.

Puntos Clave para Desarrolladores iOS que Usan SPM

  • SPM se integra nativamente en Xcode, eliminando la sobrecarga de configuración de CocoaPods y Carthage
  • El manifest Package.swift usa código Swift, permitiendo declaraciones de dependencias verificadas por tipos
  • Los requisitos de versión soportan rangos de versionado semántico, versiones exactas y referencias de ramas
  • Package.resolved bloquea versiones de dependencias para compilaciones reproducibles
  • Swift 6.2 agregó modos de lenguaje por target y configuraciones de seguridad de memoria estrictas
  • Swift 6.3 introdujo generación de SBOM para documentación de cumplimiento
  • Los targets binarios distribuyen XCFrameworks precompilados cuando la distribución de código fuente no es práctica
  • Las preguntas de entrevista se centran en conflictos de resolución, estrategias de migración y compromisos arquitectónicos entre SPM y alternativas

Para una preparación completa para entrevistas iOS, revisar los módulos sobre gestión de estado en SwiftUI y programación orientada a protocolos en SharpSkill.

¡Empieza a practicar!

Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.

Reto diario

¿Sabrías detectar el bug en iOS?

Un fragmento real, un bug oculto, un intento al día. Sin cuenta para probar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador de SharpSkill

Desarrollador fullstack desde hace más de 10 años. Dirige SharpSkill y responde por todo lo que se publica aquí.

Actualizado el 20 de septiembre de 2026

Compartir

Artículos relacionados