# Swift Package Manager у 2026: Створення, Публікація та Питання для Співбесід > Опануйте Swift Package Manager за допомогою цього детального посібника. Навчіться створювати пакети, керувати залежностями, публікувати бібліотеки та готуватися до питань iOS співбесід про SPM. - Published: 2026-09-20 - Updated: 2026-09-20 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- Swift Package Manager (SPM) відповідає за керування залежностями та розповсюдження пакетів у проєктах Swift. На відміну від CocoaPods чи Carthage, SPM інтегрований безпосередньо в Xcode та інструментарій Swift, не потребуючи зовнішнього встановлення. Swift 6.2 та 6.3 запровадили налаштування суворої безпеки памʼяті, ізоляцію акторів за замовчуванням та нову систему Swift Build, роблячи SPM безперечним вибором для сучасної iOS розробки. > **Що робить SPM** > > Swift Package Manager розвʼязує залежності, завантажує вихідний код, компілює модулі та звʼязує їх у фінальний бінарний файл. Єдиний файл маніфесту `Package.swift` визначає все: залежності, цілі, продукти та налаштування збірки. ## Структура та синтаксис маніфесту Package.swift Кожен Swift пакет починається з файлу `Package.swift` у кореневій директорії репозиторію. Цей маніфест використовує код Swift для оголошення структури пакета, залежностей та конфігурації збірки. ```swift // Package.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` визначає, чи пакет створює бібліотеку чи виконуваний файл. ```bash # Створення пакету бібліотеки 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 підтримує три стратегії специфікації версій: точна версія, діапазон версій та посилання на гілку або коміт. Вибір впливає на відтворюваність та гнучкість. ```swift // Package.swift 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 репозиторію, виберіть правило версії та визначте, які цілі повинні підключати залежність. ```swift // AppDelegate.swift 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 дозволяє швидку ітерацію без публікації проміжних версій. Ця техніка підходить для конфігурацій монорепозиторію та розробки функцій. ```swift // Package.swift у споживаючому пакеті dependencies: [ // Локальний шлях для розробки .package(path: "../NetworkKit"), // Віддалений URL для релізу // .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0") ] ``` Перемикання між локальними та віддаленими залежностями здійснюється шляхом коментування неактивного рядка. Xcode та Swift CLI розвʼязують шляхові залежності відносно споживаючого пакету. ## Публікація Swift пакету на GitHub Публікація вимагає Git репозиторію з тегами семантичних версій. SPM розглядає теги Git як версії релізів. [Swift Package Index](https://swiftpackageindex.com) автоматично індексує публічні пакети. ```bash # Ініціалізація репозиторію та 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") ``` Дотримуйтесь конвенцій [семантичного версіонування](https://semver.org): збільшуйте мажорну версію для несумісних змін, мінорну для нових функцій і патч для виправлень помилок. SPM припускає дотримання цих правил при розвʼязанні вимог версії `from:`. ## Налаштування пакетів у Swift 6.2 та 6.3 Swift 6.2 запровадив конфігурацію мовного режиму для окремих цілей та налаштування суворої безпеки памʼяті. Swift 6.3 додає інтеграцію Swift Build як опціональну систему збірки. ```swift // Package.swift з функціями Swift 6.2+ 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 перелічують усі залежності та їхні версії для аудиту безпеки та регуляторної відповідності. ```bash # Генерація SBOM у форматі CycloneDX swift build --sbom-spec cyclonedx # Генерація SBOM за допомогою спеціальної підкоманди swift package generate-sbom --format spdx # Результат включає: # - Назву та версію пакета # - Усі транзитивні залежності # - Інформацію про ліцензії # - URL репозиторіїв-джерел ``` Корпоративні середовища та державні контракти все частіше вимагають документації SBOM. Формати CycloneDX та SPDX інтегруються зі стандартними інструментами сканування вразливостей. ## Бінарні цілі та розповсюдження XCFramework Бінарні цілі дозволяють розповсюджувати попередньо скомпільовані фреймворки замість вихідного коду. XCFramework обʼєднує бінарні файли для кількох платформ та архітектур. ```swift // Package.swift з бінарною ціллю 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 пакетів](https://developer.apple.com/documentation/xcode/swift-packages) охоплює офіційні інструменти. **П: Що відбувається під час розвʼязання залежностей?** SPM рекурсивно читає маніфести `Package.swift`, будуючи граф залежностей. Потім застосовує обмеження версій, щоб знайти сумісні версії для всіх пакетів. Розвʼязувач записує точні версії до `Package.resolved`. Конфлікти виникають, коли два пакети вимагають несумісних версій спільної залежності. **П: Як розвʼязати конфлікт діамантової залежності?** Коли пакет A і B обидва залежать від пакета C з несумісними вимогами версій, SPM не може розвʼязати залежності. Рішення включають: оновлення одного споживача для підтримки ширшого діапазону версій, форк обмежувального пакета або використання псевдонімів модулів, якщо конфлікт між різними пакетами з однаковою назвою модуля. ```swift // Псевдоніми модулів для конфліктів назв .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](https://swiftpackageindex.com). ```ruby # До: Podfile pod 'Alamofire', '~> 5.9' pod 'SwiftyJSON', '~> 5.0' pod 'Kingfisher', '~> 7.0' ``` ```swift // Після: Залежності пакетів у 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** > > Коментар `// 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](/technologies/ios/interview-questions/swiftui-state-management) та [протоколо-орієнтоване програмування](/technologies/ios/interview-questions/protocol-oriented-programming) на SharpSkill. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/uk/blog/ios/swift-package-manager-tutorial-2026