Swift Package Manager у 2026: Створення, Публікація та Питання для Співбесід
Опануйте Swift Package Manager за допомогою цього детального посібника. Навчіться створювати пакети, керувати залежностями, публікувати бібліотеки та готуватися до питань iOS співбесід про SPM.

Swift Package Manager (SPM) відповідає за керування залежностями та розповсюдження пакетів у проєктах Swift. На відміну від CocoaPods чи Carthage, SPM інтегрований безпосередньо в Xcode та інструментарій Swift, не потребуючи зовнішнього встановлення. Swift 6.2 та 6.3 запровадили налаштування суворої безпеки памʼяті, ізоляцію акторів за замовчуванням та нову систему Swift Build, роблячи SPM безперечним вибором для сучасної iOS розробки.
Swift Package Manager розвʼязує залежності, завантажує вихідний код, компілює модулі та звʼязує їх у фінальний бінарний файл. Єдиний файл маніфесту Package.swift визначає все: залежності, цілі, продукти та налаштування збірки.
Структура та синтаксис маніфесту Package.swift
Кожен Swift пакет починається з файлу Package.swift у кореневій директорії репозиторію. Цей маніфест використовує код Swift для оголошення структури пакета, залежностей та конфігурації збірки.
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"]
)
]
)Масив platforms визначає мінімальні версії розгортання. Секція products визначає, що можуть імпортувати інші пакети. Секція targets перелічує одиниці компіляції з їхніми відповідними залежностями.
Створення Swift пакету з командного рядка
Команда swift package init створює каркас нового пакета зі стандартною структурою директорій. Прапорець --type визначає, чи пакет створює бібліотеку чи виконуваний файл.
# Створення пакету бібліотеки
mkdir NetworkKit && cd NetworkKit
swift package init --type=library
# Згенерована структура:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │ └── NetworkKit/
# │ └── NetworkKit.swift
# └── Tests/
# └── NetworkKitTests/
# └── NetworkKitTests.swiftВиконання swift build компілює пакет. Виконання swift test запускає набір тестів. Обидві команди використовують конфігурацію з Package.swift без додаткового налаштування.
Вимоги до версій залежностей та їх розвʼязання
SPM підтримує три стратегії специфікації версій: точна версія, діапазон версій та посилання на гілку або коміт. Вибір впливає на відтворюваність та гнучкість.
dependencies: [
// Семантичне версіонування: від 5.9.0 до наступної мажорної версії
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
// Точна версія: заблоковано на 5.9.1
.package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
// Діапазон версій: від 5.8.0 до 5.9.9
.package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
// Посилання на гілку: для розробки
.package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
// Посилання на коміт: прикріплено до конкретного коміту
.package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]Файл Package.resolved записує точні версії, визначені під час розвʼязання залежностей. Цей файл слід комітити до системи контролю версій для відтворюваних збірок серед членів команди та CI систем.
Посилання на гілки та коміти обходять семантичне версіонування. Використання branch: "main" у продакшен застосунку означає, що будь-який push до main може зламати збірку. Посилання на гілки слід залишати для активної розробки проти невипущених функцій.
Додавання пакетів до проєкту Xcode
Xcode інтегрує SPM через меню File. Перейдіть до File, потім Add Package Dependencies. Введіть URL репозиторію, виберіть правило версії та визначте, які цілі повинні підключати залежність.
import UIKit
import Alamofire // Доступний після додавання через 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 зберігає посилання на пакети у файлі .xcodeproj, а розвʼязані версії в Package.resolved у корені проєкту. Папка Derived Data кешує завантажені пакети.
Розробка локальних пакетів із шляховими залежностями
Під час розробки вказівка на локальний шлях замість віддаленого URL дозволяє швидку ітерацію без публікації проміжних версій. Ця техніка підходить для конфігурацій монорепозиторію та розробки функцій.
dependencies: [
// Локальний шлях для розробки
.package(path: "../NetworkKit"),
// Віддалений URL для релізу
// .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]Перемикання між локальними та віддаленими залежностями здійснюється шляхом коментування неактивного рядка. Xcode та Swift CLI розвʼязують шляхові залежності відносно споживаючого пакету.
Готовий до співбесід з iOS?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
Публікація Swift пакету на GitHub
Публікація вимагає Git репозиторію з тегами семантичних версій. SPM розглядає теги Git як версії релізів. Swift Package Index автоматично індексує публічні пакети.
# Ініціалізація репозиторію та 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
# Створення тегу версії
git tag 1.0.0
git push origin 1.0.0
# Інші пакети тепер можуть залежати від:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")Дотримуйтесь конвенцій семантичного версіонування: збільшуйте мажорну версію для несумісних змін, мінорну для нових функцій і патч для виправлень помилок. SPM припускає дотримання цих правил при розвʼязанні вимог версії from:.
Налаштування пакетів у Swift 6.2 та 6.3
Swift 6.2 запровадив конфігурацію мовного режиму для окремих цілей та налаштування суворої безпеки памʼяті. Swift 6.3 додає інтеграцію Swift Build як опціональну систему збірки.
import PackageDescription
let package = Package(
name: "SafeNetworkKit",
platforms: [.iOS(.v17)],
products: [
.library(name: "SafeNetworkKit", targets: ["SafeNetworkKit"])
],
targets: [
.target(
name: "SafeNetworkKit",
swiftSettings: [
// Увімкнення мовного режиму Swift 6 тільки для цієї цілі
.swiftLanguageMode(.v6),
// Увімкнення суворої перевірки безпеки памʼяті (SE-0458)
.enableExperimentalFeature("StrictMemorySafety"),
// Налаштування ізоляції акторів за замовчуванням (SE-0466)
.enableExperimentalFeature("GlobalActorIsolation")
]
)
]
)Налаштування swiftLanguageMode дозволяє поступове впровадження функцій Swift 6 у кодовій базі. Цілі можуть використовувати різні мовні режими в межах одного пакета.
Генерація SBOM для відповідності вимогам безпеки
SE-0509 додав нативну генерацію Software Bill of Materials у Swift 6.3. Документи SBOM перелічують усі залежності та їхні версії для аудиту безпеки та регуляторної відповідності.
# Генерація SBOM у форматі CycloneDX
swift build --sbom-spec cyclonedx
# Генерація SBOM за допомогою спеціальної підкоманди
swift package generate-sbom --format spdx
# Результат включає:
# - Назву та версію пакета
# - Усі транзитивні залежності
# - Інформацію про ліцензії
# - URL репозиторіїв-джерелКорпоративні середовища та державні контракти все частіше вимагають документації SBOM. Формати CycloneDX та SPDX інтегруються зі стандартними інструментами сканування вразливостей.
Бінарні цілі та розповсюдження XCFramework
Бінарні цілі дозволяють розповсюджувати попередньо скомпільовані фреймворки замість вихідного коду. XCFramework обʼєднує бінарні файли для кількох платформ та архітектур.
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..."
)
]
)
// Генерація контрольної суми:
// swift package compute-checksum AnalyticsSDK-2.0.0.xcframework.zipБінарні цілі скорочують час збірки для споживачів та захищають пропрієтарні реалізації. Контрольна сума забезпечує цілісність завантаження.
Поширені питання співбесід про Swift Package Manager
Технічні співбесіди на iOS позиції часто включають питання про SPM. Діапазон охоплює від базового використання до архітектурних рішень.
П: Чим SPM відрізняється від CocoaPods та Carthage?
SPM інтегрується з Xcode та інструментарієм Swift без зовнішніх інструментів. CocoaPods використовує центральний репозиторій специфікацій та змінює структуру workspace Xcode. Carthage збирає фреймворки в окремому кроці без інтеграції з Xcode. SPM розвʼязує залежності та збирає в єдиному уніфікованому процесі. Документація Apple щодо Swift пакетів охоплює офіційні інструменти.
П: Що відбувається під час розвʼязання залежностей?
SPM рекурсивно читає маніфести Package.swift, будуючи граф залежностей. Потім застосовує обмеження версій, щоб знайти сумісні версії для всіх пакетів. Розвʼязувач записує точні версії до Package.resolved. Конфлікти виникають, коли два пакети вимагають несумісних версій спільної залежності.
П: Як розвʼязати конфлікт діамантової залежності?
Коли пакет A і B обидва залежать від пакета C з несумісними вимогами версій, SPM не може розвʼязати залежності. Рішення включають: оновлення одного споживача для підтримки ширшого діапазону версій, форк обмежувального пакета або використання псевдонімів модулів, якщо конфлікт між різними пакетами з однаковою назвою модуля.
// Псевдоніми модулів для конфліктів назв
.target(
name: "MyApp",
dependencies: [
.product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
]
)П: Коли використовувати бінарну ціль замість розповсюдження вихідного коду?
Бінарні цілі підходять для пропрієтарних SDK, де розкриття коду неприпустиме, великих залежностей, де час компіляції впливає на продуктивність розробників, та попередньо скомпільованих бібліотек постачальників. Розповсюдження вихідного коду залишається переважним для проєктів з відкритим кодом та внутрішніх бібліотек, де налагодження в залежностях додає цінності.
Міграція з CocoaPods до Swift Package Manager
Міграція вимагає заміни записів Podfile посиланнями на пакети SPM. Не всі CocoaPods мають еквіваленти SPM, тому перед початком перевірте доступність на Swift Package Index.
# До: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'// Після: Залежності пакетів у Xcode
// File > Add Package Dependencies для кожного:
// 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Після міграції видаліть Podfile, Podfile.lock та директорію Pods. Виконання pod deintegrate видаляє модифікації workspace CocoaPods. Інструкції import у файлах Swift залишаються незмінними.
Найкращі практики SPM для продакшен застосунків
- Закріплюйте мажорні версії за допомогою
from:для стабільності, отримуючи мінорні оновлення та патчі - Комітьте
Package.resolvedдля забезпечення відтворюваних збірок у команді - Використовуйте локальні пакети під час активної розробки, переключаючись на віддалені URL перед мерджем
- Відокремлюйте залежності тільки для тестів за допомогою
testTarget, щоб уникнути їх включення в релізні збірки - Документуйте мінімальну версію інструментів Swift на початку маніфесту:
// swift-tools-version: 5.10 - Перевіряйте збірки пакетів на CI перед тегуванням релізів
Коментар // swift-tools-version: повинен зʼявитися у першому рядку Package.swift. Він визначає, яку версію API PackageDescription використовує маніфест. Swift 6.0 додав гнучкість, дозволяючи цьому коментарю бути в наступних рядках для заголовків ліцензій.
Ключові висновки для iOS розробників, що використовують SPM
- SPM інтегрується нативно з Xcode, усуваючи накладні витрати на налаштування CocoaPods та Carthage
- Маніфест
Package.swiftвикористовує код Swift, забезпечуючи типізовані оголошення залежностей - Вимоги версій підтримують діапазони семантичного версіонування, точні версії та посилання на гілки
Package.resolvedблокує версії залежностей для відтворюваних збірок- Swift 6.2 додав мовні режими для окремих цілей та налаштування суворої безпеки памʼяті
- Swift 6.3 запровадив генерацію SBOM для документації відповідності
- Бінарні цілі розповсюджують попередньо скомпільовані XCFramework, коли розповсюдження вихідного коду непрактичне
- Питання співбесід фокусуються на конфліктах розвʼязання, стратегіях міграції та архітектурних компромісах між SPM та альтернативами
Для комплексної підготовки до iOS співбесід перегляньте модулі керування станом SwiftUI та протоколо-орієнтоване програмування на SharpSkill.
Починай практикувати!
Перевір свої знання з нашими симуляторами співбесід та технічними тестами.
Чи знайдеш ти помилку в iOS?
Справжній фрагмент коду, прихована помилка, одна спроба на день. Щоб спробувати, акаунт не потрібен.

Автор:
Anthony Fillion-MailletЗасновник SharpSkill
Fullstack-розробник понад 10 років. Керує SharpSkill і відповідає за все, що тут публікується.
Оновлено 20 вересня 2026 р.
Поділитися
Пов'язані статті

CloudKit зі SwiftUI у 2026: патерни синхронізації між пристроями
Повний посібник із впровадження синхронізації CloudKit зі SwiftUI: CKSyncEngine, інтеграція зі SwiftData, розв'язання конфліктів і найкращі практики для iOS 2026.

Combine vs async/await у Swift: Шаблони Прогресивної Міграції
Повний посібник з міграції з Combine на async/await у Swift: прогресивні стратегії, шаблони мостування та співіснування парадигм у iOS-кодових базах.

Питання співбесід з доступності iOS у 2026: VoiceOver і Dynamic Type
Підготовка до співбесід з iOS із ключовими питаннями про доступність: VoiceOver, Dynamic Type, семантичні traits та аудити.