Swift Package Manager em 2026: Criação, Publicação e Perguntas de Entrevista

Guia completo sobre Swift Package Manager. Aprenda a criar pacotes Swift, gerenciar dependências, publicar bibliotecas e se preparar para entrevistas iOS.

Swift Package Manager em 2026: Criação, Publicação e Perguntas de Entrevista

Swift Package Manager (SPM) gerencia a distribuição de dependências e pacotes para projetos Swift. Diferente do CocoaPods ou Carthage, o SPM se integra diretamente no Xcode e na cadeia de ferramentas Swift, sem necessidade de instalação externa. Swift 6.2 e 6.3 introduziram configurações de segurança de memória estritas, isolamento de atores por padrão e o novo sistema Swift Build, tornando o SPM a escolha definitiva para desenvolvimento iOS moderno.

Funcionamento do SPM

Swift Package Manager resolve dependências, baixa código fonte, compila módulos e os vincula ao binário final. Um único arquivo manifest Package.swift define tudo: dependências, targets, produtos e configurações de compilação.

Estrutura e Sintaxe do Manifest Package.swift

Cada pacote Swift começa com um arquivo Package.swift na raiz do repositório. Este manifest usa código Swift para declarar a estrutura do pacote, as dependências e a configuração de compilação.

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"]
        )
    ]
)

O array platforms especifica os alvos de deployment mínimos. A seção products define o que outros pacotes podem importar. A seção targets lista as unidades de compilação com suas respectivas dependências.

Criar um Pacote Swift pela Linha de Comando

O comando swift package init gera um novo pacote com a estrutura de diretórios padrão. A flag --type determina se o pacote produz uma biblioteca ou um executável.

bash
# Criar um pacote de biblioteca
mkdir NetworkKit && cd NetworkKit
swift package init --type=library

# Estrutura gerada:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │   └── NetworkKit/
# │       └── NetworkKit.swift
# └── Tests/
#     └── NetworkKitTests/
#         └── NetworkKitTests.swift

Executar swift build compila o pacote. Executar swift test executa a suíte de testes. Ambos os comandos usam a configuração do Package.swift sem configuração adicional.

Especificação de Versões e Resolução de Dependências

O SPM suporta três estratégias de especificação de versão: versão exata, intervalo de versões e referência de branch ou commit. A escolha afeta a reprodutibilidade e flexibilidade.

Package.swiftswift
dependencies: [
    // Versionamento semântico: 5.9.0 até a próxima versão major
    .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
    
    // Versão exata: travada em 5.9.1
    .package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
    
    // Intervalo de versões: 5.8.0 a 5.9.9
    .package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
    
    // Referência de branch: para desenvolvimento
    .package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
    
    // Referência de commit: fixada em um commit específico
    .package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]

O arquivo Package.resolved registra as versões exatas resolvidas durante a resolução de dependências. Este arquivo deve ser commitado no controle de versão para builds reproduzíveis entre membros da equipe e sistemas de CI.

Dependências de Branch em Produção

As referências de branch e commit ignoram o versionamento semântico. Usar branch: "main" em um aplicativo em produção significa que qualquer push para main pode quebrar o build. As referências de branch devem ser reservadas para desenvolvimento ativo contra funcionalidades não publicadas.

Adicionar Pacotes a um Projeto Xcode

O Xcode integra o SPM através do menu Arquivo. Navegar até File, depois Add Package Dependencies. Inserir a URL do repositório, selecionar a regra de versão e escolher quais targets devem vincular a dependência.

AppDelegate.swiftswift
import UIKit
import Alamofire // Disponível após adicionar via 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
    }
}

O Xcode armazena as referências de pacotes no arquivo .xcodeproj e as versões resolvidas em Package.resolved na raiz do projeto. A pasta Derived Data armazena em cache os pacotes baixados.

Desenvolvimento Local com Dependências de Caminho

Durante o desenvolvimento, apontar para um caminho local em vez de uma URL remota permite iteração rápida sem publicar versões intermediárias. Esta técnica é adequada para configurações monorepo e desenvolvimento de funcionalidades.

Package.swift no pacote consumidorswift
dependencies: [
    // Caminho local para desenvolvimento
    .package(path: "../NetworkKit"),
    
    // URL remota para release
    // .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]

Alternar entre dependências locais e remotas comentando a linha inativa. O Xcode e o CLI do Swift resolvem dependências de caminho relativas ao pacote consumidor.

Pronto para mandar bem nas entrevistas de iOS?

Pratique com nossos simuladores interativos, flashcards e testes tecnicos.

Publicar um Pacote Swift no GitHub

A publicação requer um repositório Git com tags de versão semântica. O SPM trata tags Git como versões de release. O Swift Package Index indexa pacotes públicos automaticamente.

bash
# Inicializar repositório e fazer 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

# Criar tag de versão
git tag 1.0.0
git push origin 1.0.0

# Outros pacotes agora podem depender de:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")

Seguir as convenções de versionamento semântico: incrementar a versão major para mudanças incompatíveis, minor para novas funcionalidades e patch para correções de bugs. O SPM assume aderência a estas regras ao resolver requisitos de versão from:.

Configurações de Pacotes Swift 6.2 e 6.3

Swift 6.2 introduziu configuração de modo de linguagem por target e configurações de segurança de memória estritas. Swift 6.3 adiciona integração do Swift Build como sistema de compilação opcional.

Package.swift com recursos do 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 apenas para este target
                .swiftLanguageMode(.v6),
                // Habilitar verificação estrita de segurança de memória (SE-0458)
                .enableExperimentalFeature("StrictMemorySafety"),
                // Definir isolamento de ator padrão (SE-0466)
                .enableExperimentalFeature("GlobalActorIsolation")
            ]
        )
    ]
)

A configuração swiftLanguageMode permite adoção gradual de recursos do Swift 6 em uma base de código. Os targets podem usar diferentes modos de linguagem dentro do mesmo pacote.

Geração de SBOM para Conformidade de Segurança

SE-0509 adicionou geração nativa de Software Bill of Materials no Swift 6.3. Documentos SBOM listam todas as dependências e suas versões para auditoria de segurança e conformidade regulatória.

bash
# Gerar SBOM no formato CycloneDX
swift build --sbom-spec cyclonedx

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

# A saída inclui:
# - Nome e versão do pacote
# - Todas as dependências transitivas
# - Informações de licença
# - URLs dos repositórios fonte

Ambientes empresariais e contratos governamentais exigem cada vez mais documentação SBOM. Os formatos CycloneDX e SPDX se integram com ferramentas padrão de varredura de vulnerabilidades.

Targets Binários e Distribuição de XCFramework

Targets binários permitem distribuição de frameworks pré-compilados em vez de código fonte. XCFrameworks agrupam binários para múltiplas plataformas e arquiteturas.

Package.swift com target binárioswift
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..."
        )
    ]
)

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

Targets binários reduzem tempos de compilação para consumidores e protegem implementações proprietárias. O checksum garante a integridade do download.

Perguntas Comuns de Entrevista sobre Swift Package Manager

Entrevistas técnicas para posições iOS frequentemente incluem perguntas sobre SPM. Estas variam desde uso básico até decisões arquiteturais.

P: Como o SPM difere do CocoaPods e Carthage?

O SPM se integra ao Xcode e à cadeia de ferramentas Swift sem ferramentas externas. CocoaPods usa um repositório central de especificações e modifica a estrutura do workspace do Xcode. Carthage compila frameworks em uma etapa separada sem integração com Xcode. O SPM resolve dependências e compila em um único processo unificado. A documentação da Apple sobre pacotes Swift cobre as ferramentas oficiais.

P: O que acontece durante a resolução de dependências?

O SPM lê os manifests Package.swift recursivamente, construindo um grafo de dependências. Em seguida, aplica restrições de versão para encontrar versões compatíveis para todos os pacotes. O resolvedor escreve versões exatas em Package.resolved. Conflitos ocorrem quando dois pacotes requerem versões incompatíveis de uma dependência compartilhada.

P: Como lidar com um conflito de dependência em diamante?

Quando os pacotes A e B dependem do pacote C com requisitos de versão incompatíveis, a resolução do SPM falha. As soluções incluem: atualizar um consumidor para suportar um intervalo de versões mais amplo, fazer fork do pacote restritivo, ou usar aliasing de módulo se o conflito for entre diferentes pacotes com o mesmo nome de módulo.

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

P: Quando usar um target binário em vez de distribuição de código fonte?

Targets binários são adequados para SDKs proprietários onde a exposição do código fonte é inaceitável, grandes dependências onde o tempo de compilação afeta a produtividade do desenvolvedor, e bibliotecas de vendor pré-compiladas. A distribuição de código fonte permanece preferível para projetos de código aberto e bibliotecas internas onde depurar dentro das dependências agrega valor.

Migrar do CocoaPods para Swift Package Manager

A migração requer substituir entradas do Podfile por referências de pacotes SPM. Nem todos os CocoaPods têm equivalentes SPM, então é necessário verificar a disponibilidade no Swift Package Index antes de começar.

ruby
# Antes: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'
swift
// Depois: Dependências de pacotes no Xcode
// File > Add Package Dependencies para cada:
// 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

Remover o Podfile, Podfile.lock e o diretório Pods após a migração. Executar pod deintegrate para remover modificações do workspace do CocoaPods. As declarações de import em arquivos Swift permanecem inalteradas.

Melhores Práticas do SPM para Aplicativos em Produção

  • Fixar versões major com from: para estabilidade enquanto recebe atualizações minor e patches
  • Commitar Package.resolved para garantir builds reproduzíveis na equipe
  • Usar pacotes locais durante desenvolvimento ativo, mudando para URLs remotas antes de fazer merge
  • Separar dependências apenas de teste usando testTarget para evitar incluí-las em builds de release
  • Documentar a versão mínima de ferramentas Swift no topo do manifest: // swift-tools-version: 5.10
  • Validar builds de pacotes no CI antes de criar tags de release
Versão de Ferramentas Swift

O comentário // swift-tools-version: deve aparecer na primeira linha do Package.swift. Ele determina qual versão da API PackageDescription o manifest usa. Swift 6.0 adicionou flexibilidade para permitir este comentário em linhas subsequentes para cabeçalhos de licença.

Pontos Chave para Desenvolvedores iOS Usando SPM

  • SPM se integra nativamente no Xcode, eliminando a sobrecarga de configuração do CocoaPods e Carthage
  • O manifest Package.swift usa código Swift, permitindo declarações de dependências verificadas por tipos
  • Os requisitos de versão suportam intervalos de versionamento semântico, versões exatas e referências de branches
  • Package.resolved trava versões de dependências para builds reproduzíveis
  • Swift 6.2 adicionou modos de linguagem por target e configurações de segurança de memória estritas
  • Swift 6.3 introduziu geração de SBOM para documentação de conformidade
  • Targets binários distribuem XCFrameworks pré-compilados quando a distribuição de código fonte é impraticável
  • Perguntas de entrevista focam em conflitos de resolução, estratégias de migração e trade-offs arquiteturais entre SPM e alternativas

Para preparação completa para entrevistas iOS, revisar os módulos sobre gerenciamento de estado em SwiftUI e programação orientada a protocolos no SharpSkill.

Comece a praticar!

Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.

Desafio do dia

Você saberia encontrar o bug em iOS?

Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador da SharpSkill

Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.

Atualizado em 20 de setembro de 2026

Compartilhar

Artigos relacionados