SPM: ano ito, Swift Package Manager at Package.swift

May-akda: IT Sectr Nai-publish: 2026-02-13 Oras ng pagbabasa: 11 min

SPM (Swift Package Manager) — ang built-in na package manager ng Swift ecosystem, na binuo ng Apple para i-automate ang pagkonekta, pag-build, at pag-update ng mga third-party na library. Ang SPM ay bahagi ng Swift compiler simula sa bersyon 3.0 (2016) at hindi nangangailangan ng hiwalay na pag-install. Hindi tulad ng CocoaPods at Carthage, ang SPM ay direktang isinama sa compiler at Xcode, na ginagawa itong karaniwang tool para sa pamamahala ng dependency sa mga modernong Swift project. Sa artikulong ito, tatalakayin natin ang istraktura ng Package.swift, mga SPM command, pagsulat ng sariling mga package, at migration mula sa mga alternatibong manager.

Mga pangunahing punto

  • SPM (Swift Package Manager) — built-in na package manager sa Swift compiler, hindi nangangailangan ng hiwalay na pag-install; gumagana sa iOS, macOS, Linux, at mga server platform.
  • Package.swift — manifest file na naglalarawan ng pangalan ng package, mga platform, dependency, at target na module (targets) sa declarative format.
  • Nilulutas ng SPM ang mga dependency ayon sa semantic versioning (SemVer), nag-cache ng source code, at nagba-build ng mga package nang magkatulad para sa bilis.
  • Mga command: swift package init (gumawa ng package), swift package update (i-update ang mga dependency), swift build (mag-build), swift test (magpatakbo ng mga test).
  • Ang migration mula sa CocoaPods/Carthage patungo sa SPM ay ginagawa sa pamamagitan ng Xcode: File → Add Package Dependency, pagkatapos ay tatanggalin ang podfile at Cartfile.

Ano ang SPM?

SPM (Swift Package Manager) — ang opisyal na package manager para sa Swift language, na naka-embed sa swiftc compiler at Xcode development environment. Pinapayagan nito ang mga developer na kumonekta sa mga third-party na library, pamahalaan ang kanilang mga bersyon, at mag-publish ng sariling mga package. Unang lumitaw ang SPM sa Swift 3.0 (Setyembre 2016) bilang isang command-line tool, at simula sa Xcode 11 (2019) ay nakakuha ng buong integration sa graphical interface — ngayon ang mga dependency ay idinaragdag sa pamamagitan ng menu na File → Add Packages.

Awtomatikong dina-download ng SPM ang source code ng mga dependency mula sa mga Git repository, bina-build ang mga ito nang magkatulad sa pangunahing proyekto, at nag-cache ng mga resulta upang mas mabilis ang mga pag-rebuild. Hindi tulad ng CocoaPods, hindi gumagawa ang SPM ng hiwalay na workspace (xcworkspace) — ang mga dependency ay nagiging bahagi ng pangunahing Xcode project. Ayon sa Swift.org Developer Survey (2024), 67% ng mga iOS developer ang gumagamit ng SPM, na ginagawa itong pinakasikat na tool sa pamamahala ng dependency sa Swift ecosystem.

Sinusuportahan ng SPM ang tatlong platform: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux), at server Swift (Vapor, Kitura). Sa Linux, ganap na gumagana ang SPM sa pamamagitan ng command line nang walang Xcode.

Paano gumagana ang Swift Package Manager

Ang SPM ay binuo sa paligid ng tatlong pangunahing konsepto: mga package (packages), mga produkto (products), at mga target (targets). Ang package ay isang Git repository na may manifest na Package.swift. Ang produkto ay resulta ng build (library o executable file). Ang target ay isang module sa loob ng package na nagko-compile sa isang build unit.

Kapag nagdagdag ang developer ng dependency sa Package.swift, ginagawa ng SPM ang mga sumusunod na hakbang:

  1. Pag-clone — Dina-download ng SPM ang Git repository ng dependency mula sa tinukoy na URL.
  2. Pag-resolve ng bersyon — sinusuri ang mga SemVer tag (hal. 2.1.3) at pinipili ang angkop na bersyon sa loob ng tinukoy na saklaw.
  3. Transitibong pag-resolve — sinusuri ang mga dependency ng mga dependency at bubuo ng graph nang walang conflict ng bersyon.
  4. Pag-cache — ini-save ang na-download na source code sa ~Library/Caches/org.swift.swiftpm/.
  5. Compilation — bina-build ang lahat ng target ng package gamit ang mga flag ng pangunahing proyekto.

Ang file na Package.resolved ay nagtatakda ng eksaktong bersyon ng lahat ng dependency upang ang team ng developer ay magtrabaho sa parehong set ng mga library. Ang file na ito ay dapat idagdag sa version control system (git).

Ang pangunahing bentahe ng SPM kumpara sa mga alternatibo — kawalan ng sentralisadong rehistro. Ang mga package ay maaaring nasa anumang pampublikong Git repository: GitHub, GitLab, Bitbucket, pati na rin sa sariling Git server ng kumpanya. Mula sa Swift 5.2, sinusuportahan ng SPM ang binary dependency (binary targets) — mga saradong library na ipinamamahagi sa pamamagitan ng XCFramework nang hindi nagbibigay ng source code.

Package.swift — manifest ng proyekto

Package.swift — ay isang Swift file na naglalarawan ng istraktura ng package at mga dependency nito. Ang file ay isinulat sa Swift mismo (hindi JSON, hindi YAML), na nagbibigay-daan sa paggamit ng conditional logic, computed constants, at functions sa loob ng manifest.

Pangunahing istraktura ng Package.swift:

swift
// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "MyLibrary",
    platforms: [
        .iOS(.v16),
        .macOS(.v13)
    ],
    products: [
        .library(
            name: "MyLibrary",
            targets: ["MyLibrary"]
        ),
    ],
    dependencies: [
        .package(url: "https://github.com/Alamofire/Alamofire.git",
                 from: "5.9.0"),
        .package(url: "https://github.com/onevcat/Kingfisher.git",
                 from: "7.12.0"),
    ],
    targets: [
        .target(
            name: "MyLibrary",
            dependencies: [
                "Alamofire",
                "Kingfisher"
            ]
        ),
        .testTarget(
            name: "MyLibraryTests",
            dependencies: ["MyLibrary"]
        ),
    ]
)

Talakayin natin ang mga pangunahing elemento:

  • // swift-tools-version: 5.9 — directive na nagpapahiwatig ng bersyon ng SPM; ang magagamit na syntax ng manifest ay nakadepende dito.
  • name — pangalan ng package na ipinapakita sa Xcode at ginagamit sa mga reference ng dependency.
  • platforms — pinakamababang bersyon ng mga platform; hindi papayagan ng SPM na i-build ang package sa mas lumang bersyon ng OS.
  • products — kung ano ang "ini-export" ng package: library (.library) o executable file (.executable).
  • dependencies — listahan ng mga panlabas na package na may URL at bersyon; sinusuportahan ang from:, exact:, branch:, revision:.
  • targets — mga build target; bawat target ay naglalaman ng listahan ng mga dependency, resources, at swift file mula sa kaukulang direktoryo (Sources/TargetName/).

Halimbawa ng pagtukoy ng eksaktong bersyon, branch, at commit:

swift
dependencies: [
    .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git",
             exact: "1.17.3"),
    .package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",
             branch: "main"),
    .package(url: "https://github.com/apple/swift-log.git",
             revision: "e5c6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4"),
]

Mula sa Swift 5.9, idinagdag ang suporta para sa static/framework at linkerSettings sa Package.swift, na nagbibigay-daan sa mas tumpak na configuration ng pag-link para sa static at dynamic na library.

Mga pangunahing SPM command

Ang Swift Package Manager ay nagbibigay ng set ng mga command para sa pagtatrabaho sa pamamagitan ng terminal. Ang mga command ay pinapatakbo mula sa root directory ng package (kung saan matatagpuan ang Package.swift).

bash
# Gumawa ng bagong package na may library
swift package init --type library

# Gumawa ng executable package (console application)
swift package init --type executable

# I-build ang proyekto
swift build

# I-build sa release configuration
swift build -c release

# Patakbuhin ang mga test
swift test

# Patakbuhin ang partikular na test
swift test --filter "MyLibraryTests/testExample"

# I-download at i-resolve ang mga dependency
swift package resolve

# I-update ang mga dependency sa pinakabagong available na bersyon
swift package update

# Ipakita ang dependency graph
swift package show-dependencies

# Linisin ang build cache
swift package clean

# Bumuo ng Xcode project (bago ang Xcode 11)
swift package generate-xcodeproj

Kapag nagtatrabaho sa loob ng Xcode, karamihan sa mga command na ito ay awtomatikong naisasagawa: ang mga dependency ay na-resolve kapag binuksan ang proyekto, ang build ay pinapatakbo gamit ang ⌘B, mga test gamit ang ⌘U. Gayunpaman, ang kaalaman sa mga terminal command ay kinakailangan para sa CI/CD pipelines (GitHub Actions, GitLab CI, Jenkins), kung saan hindi available ang Xcode.

Ang command na swift package resolve ay gumagawa o nag-a-update ng file na Package.resolved. Ang file na ito ay nagtatakda ng eksaktong bersyon ng lahat ng dependency, kabilang ang mga transitibo, at dapat idagdag sa git. Inirerekomenda na patakbuhin ang swift package update bago ang bawat bagong feature branch, upang magtrabaho sa kasalukuyang bersyon ng mga library.

Paggawa ng sarili mong package

Ang paggawa ng sariling SPM package ay kapaki-pakinabang para sa encapsulation ng business logic sa multi-module na proyekto at para sa pag-publish ng open-source library. Tingnan natin ang proseso nang hakbang-hakbang.

Hakbang 1: Initialization

bash
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library

Hakbang 2: Istraktura ng direktoryo

Ang command na swift package init ay gumagawa ng sumusunod na istraktura:

text
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│   └── MyNetworkKit/
│       └── MyNetworkKit.swift
└── Tests/
    └── MyNetworkKitTests/
        └── MyNetworkKitTests.swift

Awtomatikong nag-scan ang SPM ng mga direktoryo ng Sources/ at Tests/: bawat subdirectory sa loob ng Sources ay tumutugma sa isang target.

Hakbang 3: Pag-edit ng Package.swift

Magdagdag tayo ng mga dependency at i-configure ang mga target na platform:

swift
// swift-tools-version: 5.9
import PackageDescription

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

Hakbang 4: Pagsulat ng code

swift
// Sources/MyNetworkKit/MyNetworkKit.swift
import Foundation
import Alamofire

public struct NetworkClient {
    private let session: Session

    public init() {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        self.session = Session(configuration: configuration)
    }

    public func fetchData(from url: String) async throws -> Data {
        let response = try await session.request(url).serializingData().value
        return response
    }
}

Hakbang 5: Pag-publish

I-push ang package sa Git repository at gumawa ng SemVer tag:

bash
git init
git add .
git commit -m "Initial commit: MyNetworkKit"
git remote add origin https://github.com/username/MyNetworkKit.git
git push -u origin main
git tag 1.0.0
git push --tags

Pagkatapos nito, kahit sinong developer ay maaaring kumonekta sa iyong package sa pamamagitan ng .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0").

Mga halimbawa ng paggamit ng SPM

Halimbawa 1: Pagkonekta ng Alamofire para sa network requests

Alamofire — ang pinakasikat na HTTP client para sa Swift. Idagdag natin ito sa pamamagitan ng SPM at magsagawa ng GET request.

swift
import Alamofire

func fetchUsers() {
    AF.request("https://jsonplaceholder.typicode.com/users")
        .validate()
        .responseDecodable(of: [User].self) { response in
            switch response.result {
            case .success(let users):
                print("Natanggap ang \(users.count) na user")
            case .failure(let error):
                print("Error: \(error.localizedDescription)")
            }
        }
}

Halimbawa 2: Swinject — dependency injection

Ang Swinject library ay nagbibigay ng DI container para sa Swift. Kumokonekta sa pamamagitan ng .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0").

swift
import Swinject

let container = Container()
container.register(NetworkServiceProtocol.self) { _ in NetworkService() }
container.register(DataRepositoryProtocol.self) { r in
    DataRepository(networkService: r.resolve(NetworkServiceProtocol.self)!)
}

let repository = container.resolve(DataRepositoryProtocol.self)
repository?.loadData()

Halimbawa 3: Swift-log para sa structured logging

Ang swift-log package mula sa Apple — isang unified logging API na sumusuporta sa maraming backend (OSLog, console, file).

swift
import Logging

var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug

logger.info("Nagsimula ang network request", metadata: [
    "url": "\(requestURL)",
    "method": "GET"
])

logger.warning("Lumampas sa 2 segundo ang oras ng pagtugon")
logger.error("Error sa koneksyon: walang internet")

Ang tatlong halimbawang ito ay sumasaklaw sa karaniwang mga sitwasyon ng paggamit ng SPM: HTTP clients, DI containers, at system infrastructure. Ang pagpili ng mga library ay hindi sinasadya — ang Alamofire, Swinject, at swift-log ay nasa top 20 pinakasikat na Swift package sa GitHub.

Migration mula sa CocoaPods at Carthage

Kung ang proyekto ay gumagamit ng CocoaPods o Carthage, ang migration sa SPM ay ginagawa sa ilang hakbang. Ang proseso ay ligtas: ang mga SPM dependency ay maaaring magkasama sa CocoaPods at Carthage sa iisang proyekto, na nagpapahintulot ng gradual na migration.

CocoaPods → SPM

  1. Sa Xcode: File → Add Package Dependency, ilagay ang URL ng package.
  2. Pumili ng bersyon at idagdag ang package sa mga kinakailangang target.
  3. Pagkatapos idagdag ang lahat ng dependency sa pamamagitan ng SPM, tanggalin ang mga linya mula sa Podfile.
  4. Tanggalin ang .xcworkspace, buksan ang .xcodeproj, at gawin ang Clean Build Folder.

Carthage → SPM

  1. Idagdag ang mga package sa pamamagitan ng Xcode File → Add Package Dependency.
  2. Tanggalin ang mga dependency mula sa Cartfile.
  3. Tanggalin ang Carthage build scripts mula sa Build Phases.
  4. Linisin ang cache: rm -rf Carthage/ sa terminal.

Noong 2025, sinusuportahan ng SPM ang karamihan ng mga sikat na Swift library. Ang mga exception ay ilang ObjC framework na walang module map (modulemap). Kung ang isang library ay hindi pa sumusuporta sa SPM — suriin ang seksyon ng Installation sa README nito; karamihan sa mga may-akda ay nagdagdag na ng SPM support sa mga pinakabagong bersyon.

Mga madalas itanong

Paano naiiba ang SPM sa CocoaPods at Carthage?

Ang SPM ay naka-embed sa Swift compiler at Xcode, hindi nangangailangan ng pag-install sa pamamagitan ng gem o Homebrew. Ang CocoaPods ay gumagamit ng sentralisadong Specs registry at gumagawa ng hiwalay na workspace. Ang Carthage ay gumagana sa pamamagitan ng framework nang walang integration sa proyekto. Ang SPM ay ang tanging manager na isinama sa antas ng compiler: ang mga dependency ay nire-resolve, ni-ca-cache, at bina-build nang magkatulad sa pangunahing code.

Maaari bang gamitin ang SPM para sa Objective-C projects?

Oo, sinusuportahan ng SPM ang mixed Swift + Objective-C projects. Ang mga ObjC file sa loob ng SPM package ay awtomatikong napupunta sa Umbrella Header sa kondisyon ng tamang modulemap. Gayunpaman, hindi sinusuportahan ng SPM ang static na ObjC library na walang module map. Inirerekomenda na kumonekta sa ObjC library sa pamamagitan ng SPM lamang kung nagbibigay sila ng modulemap o nakasulat sa purong C.

Paano nireresolba ng SPM ang mga conflict ng bersyon?

Gumagamit ang SPM ng semantic versioning (SemVer). Kung ang package A ay nangangailangan ng Alamofire 5.8+, at ang package B ay nangangailangan ng Alamofire 5.9+, pipili ang SPM ng bersyon 5.9.x na nakakatugon sa pareho. Kung ang conflict ay hindi naresolba (isang package ay nangangailangan ng 5.x, ang isa ay 6.x), mag-uulat ang SPM ng error. Sa ganoong kaso, kailangan mong i-update ang isa sa mga package o baguhin ang dependency sa isang bersyon na katugma sa parehong pangangailangan.

Saan nakaimbak ang mga nai-download na SPM package?

Sa macOS: ~Library/Caches/org.swift.swiftpm/ at ~/Library/Developer/Xcode/DerivedData/. Sa Linux: ~cache/swiftpm/. Sa pag-build, nag-ca-cache ang SPM ng source code at mga naka-compile na object file. Para ganap na linisin ang cache, patakbuhin ang swift package reset — ang command na ito ay nagtatanggal ng dependency cache at DerivedData para sa kasalukuyang proyekto.

Sinusuportahan ba ng SPM ang mga saradong (proprietary) library?

Oo, simula sa Swift 5.2, sinusuportahan ng SPM ang binary targets. Ang saradong library ay ibinibigay bilang XCFramework, at sa Package.swift ay tinutukoy ang path sa .xcframework. Ang source code ay hindi isinasapubliko. Ang binary target ay tinutukoy sa pamamagitan ng .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework"). Ito ay nagpapahintulot sa pagkonekta ng commercial SDK nang hindi lumalabag sa mga kasunduan sa lisensya.

Buod

  • SPM (Swift Package Manager) — built-in na Swift package manager na hindi nangangailangan ng hiwalay na pag-install at isinama sa Xcode at compiler.
  • Package.swift — declarative manifest sa Swift language na naglalarawan ng pangalan ng package, platform, dependency, produkto, at build target.
  • Gumagamit ang SPM ng Git repository bilang source ng package at nireresolba ang mga bersyon ayon sa SemVer, nag-ca-cache ng source code para mapabilis ang mga pag-rebuild.
  • Mga pangunahing command: swift package init (gumawa ng package), swift build (mag-build), swift test (mag-test), swift package update (i-update ang mga dependency).
  • Ang sariling package ay ginagawa sa pamamagitan ng swift package init, nai-publish sa Git, at available sa ibang proyekto sa pamamagitan ng URL na may SemVer tag.
  • Ang migration mula sa CocoaPods/Carthage patungo sa SPM ay ligtas: ang mga dependency ay maaaring magkasama, ang migration ay ginagawa sa pamamagitan ng File → Add Package Dependency sa Xcode.
  • SPM — ang pamantayan sa pamamahala ng dependency sa Swift ecosystem, na ginagamit ng 67% ng mga iOS developer (Swift.org Developer Survey, 2024).

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din