📦 Carthage для Swift: децентрализованный менеджер зависимостей
Carthage — это децентрализованный менеджер зависимостей для экосистемы Apple (iOS, macOS, tvOS, watchOS). В отличие от CocoaPods, Carthage не модифицирует проект автоматически — он собирает фреймворки, а вы сами подключаете их к Xcode. Это даёт полный контроль над процессом сборки и минимум «магии».
Библиотека использует Carthage (название совпадает с инструментом) и работает через Cartfile — декларативный файл, в котором перечисляются зависимости. Carthage клонирует репозитории, собирает их (используя xcodebuild) и помещает готовые .framework в папку Carthage/Build. Вы вручную добавляете их в проект.
Зачем нужен Carthage? Если вы цените прозрачность, хотите избежать конфликтов версий и не любите, когда инструменты автоматически правят ваш проект. Он идеален для команд, где каждый сам решает, как подключать зависимости, и для проектов с жёсткими требованиями к безопасности сборки.
1. Установка Carthage
Carthage можно установить через Homebrew (рекомендуется) или скачать .pkg с GitHub.
# Установка через Homebrew
brew install carthage
# Проверка версии
carthage version
Если Homebrew не установлен, сначала установите его: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Для Linux или Windows Carthage официально не поддерживается (только macOS).
2. Быстрый старт — минимальный рабочий пример
Создайте новый проект Xcode (например, Single View App). Затем в корне проекта создайте файл Cartfile (без расширения) и добавьте зависимость:
# Cartfile
github "Alamofire/Alamofire" ~> 5.8
Теперь выполните команду в терминале (из папки проекта):
carthage update --platform iOS
После завершения в папке Carthage/Build/iOS появится Alamofire.framework. Откройте Xcode, перетащите этот .framework в секцию Frameworks, Libraries, and Embedded Content вашего таргета. Выберите «Embed & Sign».
Теперь можно импортировать библиотеку:
import Alamofire
// Минимальный запрос
AF.request("https://api.github.com/users/defunkt").response { response in
debugPrint(response)
}
Готово! Вы только что подключили зависимость через Carthage.
3. Основные методы и функции Carthage
Ниже приведены ключевые команды и возможности Carthage. Большинство из них вызываются из терминала.
🔹 1. carthage update
Сигнатура carthage update [--platform PLATFORM] [--configuration CONFIG] [--no-build] [--use-xcframeworks]
Что делает: Скачивает и собирает все зависимости из Cartfile.resolved (или обновляет до последних версий, если Cartfile.resolved отсутствует). Создаёт папку Carthage/Build.
# Обновить только для iOS, используя xcframeworks
carthage update --platform iOS --use-xcframeworks
🔹 2. carthage bootstrap
Сигнатура carthage bootstrap [--platform PLATFORM] [--configuration CONFIG] [--use-xcframeworks]
Что делает: Собирает зависимости, используя существующий Cartfile.resolved (без обновления версий). Идеально для CI/CD — гарантирует повторяемость сборки.
# Пересобрать всё, как указано в Cartfile.resolved
carthage bootstrap --platform macOS
🔹 3. carthage build
Сигнатура carthage build [--platform PLATFORM] [--configuration CONFIG] [--no-skip-current]
Что делает: Собирает только те зависимости, которые ещё не собраны (или флаг --no-skip-current форсирует пересборку). Полезно, если вы изменили Cartfile.
# Пересобрать все фреймворки для iOS
carthage build --platform iOS --no-skip-current
🔹 4. carthage checkout
Сигнатура carthage checkout [--use-ssh] [--no-use-binaries]
Что делает: Только клонирует/обновляет исходники зависимостей в папку Carthage/Checkouts, но не собирает их. Полезно для инспекции кода.
# Скачать исходники без сборки
carthage checkout
🔹 5. carthage outdated
Сигнатура carthage outdated
Что делает: Показывает список зависимостей, для которых доступны более новые версии, чем указаны в Cartfile.resolved.
# Проверить устаревшие пакеты
carthage outdated
🔹 6. carthage copy-frameworks
Сигнатура carthage copy-frameworks [--project-name NAME]
Что делает: Используется в Build Phases (Run Script) для копирования фреймворков из Carthage/Build в итоговый .app. Устраняет проблему с отсутствием фреймворков на устройстве.
# Пример скрипта в Xcode (вводится в Run Script)
/usr/local/bin/carthage copy-frameworks
🔹 7. carthage version
Сигнатура carthage version
Что делает: Выводит текущую версию установленного Carthage.
carthage version
# Пример вывода: 0.39.1
🔹 8. Cartfile — декларативный синтаксис
Сигнатура github "User/Repo" ~> 1.0 или binary "https://example.com/MyFramework.json" == 2.3
Что делает: Определяет правила для зависимостей. Поддерживает GitHub, Git-репозитории, бинарные фреймворки.
# Примеры строк Cartfile
github "ReactiveX/RxSwift" ~> 6.5
git "https://gitlab.com/company/private-lib.git" >= 2.0
binary "https://mycompany.com/MyFramework.json" == 1.2
🔹 9. Cartfile.resolved
Сигнатура генерируется автоматически
Что делает: Фиксирует точные версии (SHA/теги) всех зависимостей. Должен быть под версионным контролем для воспроизводимости сборок.
# Пример содержимого Cartfile.resolved
github "Alamofire/Alamofire" "5.8.1"
github "ReactiveX/RxSwift" "6.6.0"
🔹 10. --use-xcframeworks
Сигнатура флаг для update/bootstrap/build
Что делает: Указывает Carthage собирать универсальные .xcframework вместо .framework. Рекомендуется для поддержки симулятора и устройства одной сборкой.
carthage update --platform iOS --use-xcframeworks
4. Реальный практический пример (150+ строк кода)
Создадим простое приложение для iOS, которое загружает список пользователей GitHub с помощью Alamofire и отображает их в таблице. Carthage будет управлять зависимостью.
Шаг 1. Cartfile
# Cartfile
github "Alamofire/Alamofire" ~> 5.8
github "onevcat/Kingfisher" ~> 7.10
Шаг 2. Установка зависимостей
carthage update --platform iOS --use-xcframeworks
Шаг 3. Код приложения (Swift)
import UIKit
import Alamofire
import Kingfisher
// Модель пользователя GitHub
struct GitHubUser: Decodable {
let login: String
let id: Int
let avatarUrl: String
let htmlUrl: String
enum CodingKeys: String, CodingKey {
case login, id
case avatarUrl = "avatar_url"
case htmlUrl = "html_url"
}
}
// ViewController с таблицей
class UsersViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private var users: [GitHubUser] = []
private let cellIdentifier = "UserCell"
override func viewDidLoad() {
super.viewDidLoad()
title = "GitHub Users"
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
fetchUsers()
}
// MARK: - Networking with Alamofire
private func fetchUsers() {
let url = "https://api.github.com/users"
AF.request(url).responseDec Также в библиотеке
Планировщик задач на TypeScript: полное руководство по cron-библиотекам и таймерам
Event Bus и паттерн Observer в JavaScript (Node.js) — создание гибких событийных систем
Elasticsearch REST клиент для Kotlin: руководство по использованию
WebSocket в C++: библиотеки и практическое применение