CocoaPods Cheat Sheet
Overview
CocoaPods is the most widely used dependency manager for Swift and Objective-C projects on Apple platforms. It manages library dependencies for Xcode projects by resolving dependency graphs, downloading source code, and integrating libraries into an Xcode workspace. CocoaPods hosts over 90,000 libraries (called “pods”) in its centralized Trunk repository, covering everything from networking and UI components to analytics and authentication frameworks.
CocoaPods works by reading a Podfile that declares project dependencies, resolving compatible versions, downloading the libraries, and creating or updating an Xcode workspace that includes both the main project and a Pods project containing all dependencies. It handles header search paths, linker flags, build settings, and framework linking automatically. While Apple’s Swift Package Manager has gained popularity for pure Swift projects, CocoaPods remains essential for many Objective-C libraries and complex project configurations.
Installation
# Install via RubyGems (system Ruby)
sudo gem install cocoapods
# Install via Homebrew
brew install cocoapods
# Install specific version
sudo gem install cocoapods -v 1.15.0
# Using Bundler (recommended for teams)
cat > Gemfile << 'EOF'
source "https://rubygems.org"
gem "cocoapods", "~> 1.15"
EOF
bundle install
# Setup the CocoaPods master repo
pod setup
# Verify installation
pod --version
pod env
Podfile Basics
# Podfile
platform :ios, '16.0'
use_frameworks!
inhibit_all_warnings!
target 'MyApp' do
# Networking
pod 'Alamofire', '~> 5.9'
pod 'Moya', '~> 15.0'
# UI
pod 'SnapKit', '~> 5.7'
pod 'Kingfisher', '~> 7.0'
# Data
pod 'SwiftyJSON', '~> 5.0'
pod 'RealmSwift', '~> 10.0'
# Analytics
pod 'Firebase/Analytics'
pod 'Firebase/Crashlytics'
target 'MyAppTests' do
inherit! :search_paths
pod 'Quick', '~> 7.0'
pod 'Nimble', '~> 13.0'
end
target 'MyAppUITests' do
inherit! :search_paths
end
end
# Post-install hook
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
end
end
end
Version Specifiers
| Syntax | Meaning | Example |
|---|---|---|
'1.0' | Exact version | Only 1.0 |
'> 1.0' | Greater than | Any version above 1.0 |
'>= 1.0' | Greater than or equal | 1.0 or above |
'< 2.0' | Less than | Any version below 2.0 |
'<= 2.0' | Less than or equal | 2.0 or below |
'~> 1.0' | Compatible with | >= 1.0, < 2.0 |
'~> 1.5.3' | Patch-level compatible | >= 1.5.3, < 1.6.0 |
| (no version) | Latest | Always latest version |
Core Commands
# Install dependencies (first time)
pod install
# Update all pods to latest versions
pod update
# Update specific pod
pod update Alamofire
# Install without updating existing pods
pod install --repo-update
# Show outdated pods
pod outdated
# Deintegrate CocoaPods from project
pod deintegrate
# Clean CocoaPods cache
pod cache clean --all
pod cache clean Alamofire
# List installed pods
pod list
# Search for pods
pod search networking
pod search Alamofire --simple
# Get pod info
pod spec cat Alamofire
pod spec which Alamofire
# Validate Podfile syntax
pod lib lint
# Generate acknowledgements
# Auto-generated at Pods/Target Support Files/Pods-MyApp/Pods-MyApp-acknowledgements.plist
Pod Sources
# Podfile - Using different sources
# Git repository
pod 'MyPrivatePod', :git => 'https://github.com/user/repo.git'
pod 'MyPrivatePod', :git => 'https://github.com/user/repo.git', :tag => '1.0.0'
pod 'MyPrivatePod', :git => 'https://github.com/user/repo.git', :branch => 'develop'
pod 'MyPrivatePod', :git => 'https://github.com/user/repo.git', :commit => 'abc123'
# Local path
pod 'MyLocalPod', :path => '../MyLocalPod'
# Subspecs
pod 'Firebase/Auth'
pod 'Firebase/Firestore'
pod 'Kingfisher/SwiftUI'
# Specific source repos
source 'https://github.com/CocoaPods/Specs.git' # Public
source 'https://github.com/mycompany/private-specs.git' # Private
# Binary pods (precompiled)
pod 'GoogleMaps' # Many Google pods ship as binaries
Multi-Target Configuration
# Podfile with multiple targets and shared pods
platform :ios, '16.0'
use_frameworks!
# Shared pods used by all targets
def shared_pods
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'
end
target 'MyApp' do
shared_pods
pod 'Firebase/Analytics'
target 'MyAppTests' do
inherit! :search_paths
pod 'OHHTTPStubs/Swift'
end
end
target 'MyAppWidget' do
shared_pods
end
target 'MyAppWatch' do
platform :watchos, '9.0'
pod 'Alamofire', '~> 5.9'
end
# Abstract target (not a real Xcode target)
abstract_target 'Common' do
shared_pods
target 'MyApp' do
pod 'Firebase/Analytics'
end
target 'MyAppLite' do
# Inherits shared_pods
end
end
Creating a Pod
# Create pod template
pod lib create MyPod
# Follow prompts for language, platform, testing framework
# Pod project structure
MyPod/
├── MyPod.podspec
├── MyPod/
│ ├── Classes/
│ │ └── MyPod.swift
│ └── Assets/
├── Example/
│ ├── Podfile
│ └── MyPod.xcworkspace
├── Tests/
├── LICENSE
└── README.md
# MyPod.podspec
Pod::Spec.new do |s|
s.name = 'MyPod'
s.version = '1.0.0'
s.summary = 'A short description of MyPod.'
s.description = <<-DESC
A longer description of what MyPod does.
DESC
s.homepage = 'https://github.com/user/MyPod'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Author' => 'author@example.com' }
s.source = { :git => 'https://github.com/user/MyPod.git', :tag => s.version.to_s }
s.ios.deployment_target = '16.0'
s.swift_versions = ['5.9', '5.10']
s.source_files = 'MyPod/Classes/**/*'
s.resources = 'MyPod/Assets/**/*'
s.resource_bundles = {
'MyPod' => ['MyPod/Assets/**/*.{png,json,xib,storyboard}']
}
s.dependency 'Alamofire', '~> 5.9'
s.dependency 'SwiftyJSON', '~> 5.0'
s.frameworks = 'UIKit', 'Foundation'
# Subspecs
s.subspec 'Core' do |core|
core.source_files = 'MyPod/Classes/Core/**/*'
end
s.subspec 'Networking' do |net|
net.source_files = 'MyPod/Classes/Networking/**/*'
net.dependency 'MyPod/Core'
net.dependency 'Alamofire'
end
end
# Validate podspec
pod lib lint MyPod.podspec
pod lib lint MyPod.podspec --allow-warnings
pod lib lint MyPod.podspec --verbose
# Publish to CocoaPods trunk
pod trunk register email@example.com 'Author Name'
pod trunk push MyPod.podspec
pod trunk push MyPod.podspec --allow-warnings
# Private spec repo
pod repo add my-specs https://github.com/mycompany/specs.git
pod repo push my-specs MyPod.podspec
Advanced Usage
# Podfile hooks
pre_install do |installer|
# Modify pods before installation
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# Fix deployment target warnings
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
# Enable code coverage
config.build_settings['CLANG_ENABLE_CODE_COVERAGE'] = 'YES'
# Disable bitcode
config.build_settings['ENABLE_BITCODE'] = 'NO'
# Silence warnings from pods
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
end
end
# Modify specific pod
installer.pods_project.targets.each do |target|
if target.name == 'SomePod'
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '5.0'
end
end
end
end
# Static vs dynamic frameworks
use_frameworks! :linkage => :static
# or
use_frameworks! :linkage => :dynamic
# Conditional pods
pod 'Flipper', :configuration => 'Debug'
Troubleshooting
| Issue | Solution |
|---|---|
| ”Unable to find specification” | Run pod repo update or pod install --repo-update |
| Merge conflicts in Podfile.lock | Resolve conflicts then run pod install |
| ”No such module” in Xcode | Open .xcworkspace not .xcodeproj; clean build folder |
Slow pod install | Use --no-repo-update flag; consider CDN source |
| Build errors after update | Run pod deintegrate && pod install; clean derived data |
| ”target has transitive dependencies” | Add use_frameworks! or remove conflicting static libs |
| Version conflict | Check pod outdated; adjust version constraints in Podfile |
| Missing header files | Check search paths; run pod install after adding new pods |
| Cache issues | Run pod cache clean --all then pod install |
| M1/ARM issues | Run terminal with Rosetta or add arch -x86_64 pod install |