You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Defect: These are known bugs. The issue should also contain steps to reproduce. Feel free to fix these and submit a pull request.
Enhancement: These are planned enhancements that have not been picked up yet. If you would like to work on one, please add a comment that you are doing so.
Discussion: These are issues that can be non-issues, and encompass best practices, or plans for the future.
Quick: These are small issues, that should be able to be fixed quickly. Normally these issues don't stay around for very long.
To check: These issues may not be reproduceable, or have not been vetted by a team member.
Workaround known: These issues have had their solutions discussed, but have yet to be implemented.
####Making the Pull Request
Before submitting your pull request, please do the following:
Run rake spec and make sure all the tests pass. If you are adding new commands or features, they must include tests. If you are changing functionality, update the tests if you need to.
Add a note to the changelog describing what you changed.
Make your pull request. If it is related to an issue, add a link to the issue in the description.
TODO:
Code Style
Documentation Style
What are the main components?
CocoaPods
The CocoaPods gem which includes the command line support and the installer.
Cocoapods-core
The CocoaPods-Core gem provides support to work with the models of CocoaPods.
Xcodeproj
Xcodeproj lets you create and modify Xcode projects from Ruby. Script boring management tasks or build Xcode-friendly libraries. Also includes support for Xcode workspaces (.xcworkspace) and configuration files (.xcconfig).
Cocoapods-downloader
A small library that provides downloaders for various source types (HTTP/SVN/Git/Mercurial).
CLAide
I was born out of a need for a simple option and command parser, while still providing an API that allows you to quickly create a full featured command-line interface.
To ensure a high quality, reliable collection of Pods, the master repo is
strict about the acceptable specifications. The CocoaPods linter (see the pod spec lint command) is used to validate specifications, and no errors or warnings
are accepted.
The highest priority of the master repo is to guarantee the integrity of existing
CocoaPods installations.
In general this means that:
A specification cannot be deleted.
Specifications can be updated only if they don't affect existing installations.
Broken specifications can be updated.
Subspecs can be added as they are included by the parent specification by default.
The podspec is a shortcut to require all the dependencies specified in NAME.podspec.
Development
You can work on the library from its project. Alternatively you can work from an application project using the :path option:
pod'Name',:path=>'~/code/Pods/NAME.podspec'
You can also lint the pod against the files of its directory:
$ cd~/code/Pods/NAME
$ pod spec lint --local
Release
The release workflow can be the following.
$ cd~/code/Pods/NAME
$ edit NAME.podspec
# set the new version to 0.0.1# set the new tag to 0.0.1
$ pod spec lint --local
$ git add -A && git commit -m "Release 0.0.1."
$ git tag '0.0.1'
$ git push --tags
$ pod push master
Although the master repo is backed by a git repository, this is not required. For a repository to be valid it is only required to respect the above described file structure.
CocoaPods stores its repositories in the ~/.cocoapods/ folder.
Adding a new repo
Manually
Make a folder with the name of the repo in ~/.cocoapods/.
Populate the repository with podspecs respecting the required folder structure.
From an existing git remote
If you want to create a git backed repository you can use the $ pod repo add command.
Disambiguation
If during the installation process is resolved a Pod whose required version is present in more than one repository, the alphabetical order of the names is used to disambiguate.
TODO:
How do I podify an existing project?
How do I test the new Pod
Local Pods?
Versioning
There is, unfortunately, often an issue of developers not interpreting version
numbers well or assigning emotional value to certain version numbers.
However, arbitrary revisions as version is not a good idea for a library
manager instead of a proper version number (see Semantic
Versioning). Let us explain how, in an ideal world, we’d
prefer people to interact with it:
“I want to start using CocoaLumberjack, the current version will be fine for
now.” So the dev adds a dependency on the lib without a version requirement
and lets the manager install it which will use the latest version:
pod 'CocoaLumberjack'
Some time into the future, the dev wants to update the dependencies, and to do so runs
the install command again, which will now install the version of the lib
which is the latest version at that time.
At some point the dev is finished on the client work (or a newer version of
the lib changes the API and the changes aren’t needed) so the dev adds a
version requirement to the dependency. For instance, consider that the author
of the lib follows the semver guidelines, you can somewhat trust that between
‘1.0.7’ and ‘1.1.0’ no API changes will be made, but only bug fixes. So
instead of requiring a specific version, the dev can specify that any
‘1.0.x’ is allowed as long as it’s higher than ‘1.0.7’:
pod 'CocoaLumberjack', '~> 1.0.7'
The point is that developers can easily keep track of newer versions of dependencies,
by simply running pod install again, which they might otherwise do less if
they had to change everything manually.
CocoaPods Versioning Specifics
CocoaPods uses RubyGems versions for specifying pod spec versions. The
RubyGems Versioning Policies
describes the rules used for interpreting version numbers. The RubyGems
version specifiers describes
exactly how to use the comparison operators that specify dependency versions.
Following the pattern established in RubyGems, pre-release versions can also be
specified in CocoaPods. A pre-release of version 1.2, for example, can be
specified by '1.2.beta.3'. In this example, the dependency specifier '~>
1.2.beta' will match '1.2.beta.3'.
Documenting a Pod
TODO
Where can I ask questions?
TODO: Mailing List | Announcements and support. Feel free to ask any kind of question.
CocoaPods manages library dependencies for your Xcode project.
The dependencies for your project are specified in a single text file. CocoaPods
resolves dependencies between libraries, fetches the source code, and creates and maintains an Xcode workspace to build your project.
Ultimately the goal is to improve discoverability of, and engagement in, third
party open-source libraries by creating a more centralized ecosystem.
Installing CocoaPods
Dependencies
Ruby MRI 2.0.0 or 1.8.7 (ships with Mac OS X)
Xcode command line tools.
Installation
To install CocoaPods you can run:
$ [sudo] gem install cocoapods
To enjoy performance benefits you can install a modern Ruby like 2.0.0 through a
Ruby version manager like RVM. If you are using RVM, or equivalent, we suggest not using sudo as it may have some unintended effects on other parts of your system.
Updating CocoaPods
To update CocoaPods you can run:
$ [sudo] gem update cocoapods
If you would like to try a pre-release version of CocoaPods you can run:
$ [sudo] gem update cocoapods --pre
Troubleshooting
The gem might not be able to compile, to solve this you might need to symlink
GCC.
If you used an pre release version of Xcode you might need to update the
command line tools.
CocoaPods is not compatible with MacRuby.
What is a Podfile?
The Podfile is a specification that describes the dependencies of the
targets of one or more Xcode projects. The Podfile always creates an
implicit target, named default, which links to the first target of the
user project.
A podfile can be very simple:
pod 'AFNetworking', '~> 1.0'
An example of a more complex podfile can be:
platform :ios, '6.0'
inhibit_all_warnings!
xcodeproj `MyProject`
pod 'ObjectiveSugar', '~> 0.5'
target :test do
pod 'OCMock', '~> 2.0.1'
end
post_install do |installer|
installer.project.targets.each do |target|
puts "#{target.name}"
end
end
When starting out with a project it is likely that you will want to use
the latest version of a Pod. If this is the case, simply omit the
version requirements.
pod 'SSZipArchive'
Later on in the project you may want to freeze to a specific version of
a Pod, in which case you can specify that version number.
pod 'Objection', '0.9'
Besides no version, or a specific one, it is also possible to use
operators:
> 0.1 Any version higher than 0.1
>= 0.1 Version 0.1 and any higher version
< 0.1 Any version lower than 0.1
<= 0.1 Version 0.1 and any lower version
~> 0.1.2 Version 0.1.2 and the versions up to 0.2, not including 0.2
A list of version requirements can be specified for even more fine
grained control.
For more information, regarding versioning policy, see:
Finally, instead of a version, you can specify the :head flag. This
will use the pod’s latest version spec version, but force the download
of the ‘bleeding edge’ version. Use this with caution, as the spec
might not be compatible anymore.
pod 'Objection', :head
Using the files from a folder local to the machine.
If you wold like to use develop a Pod in tandem with its client
project you can use the local option.
pod 'AFNetworking', :path => '~/Documents/AFNetworking'
Using this option CocoaPods will assume the given folder to be the
root of the Pod and will link the files directly from there in the
Pods project. This means that your edits will persist to CocoaPods
installations.
The referenced folder can be a checkout of your your favorite SCM or
even a git submodule of the current repo.
Note that the podspec of the Pod file is expected to be in the
folder.
From a podspec in the root of a library repo.
Sometimes you may want to use the bleeding edge version of a Pod. Or a
specific revision. If this is the case, you can specify that with your
pod declaration.
To use the master branch of the repo:
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'
Or specify a commit:
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'
It is important to note, though, that this means that the version will
have to satisfy any other dependencies on the Pod by other Pods.
The podspec file is expected to be in the root of the repo, if this
library does not have a podspec file in its repo yet, you will have
to use one of the approaches outlined in the sections below.
Integrating with an Xcode project
Before you begin
Check the Specs repository to make sure the libraries you would like to use are available.
[Install CocoaPods on your computer][installing-cocoapods].
Installation
Create a [Podfile][podfile], and add your dependencies:
pod 'AFNetworking', '~> 1.0'
pod 'ObjectiveSugar', '~> 0.5'
Run $ pod install in your project directory.
Open App.xcworkspace and build.
TODO:
How do I start a new project with Cocoapods?
How do I add Cocoapods to my existing project that already uses a workspace?
Should I check in my pods folder?
TODO
What is a Podfile.lock
This file keeps track of what version of a Pod is installed. For example the
following dependency might install RestKit 0.10.3:
pod 'RestKit'
Thanks to the Podfile.lock every machine which runs pod install on the
hypothetical project will use RestKit 0.10.3 even if a newer version is
available. CocoaPods will honor this version unless the dependency is updated
on the Podfile or pod update is called. In this way CocoaPods avoids headaches
caused by unexpected changes to dependencies.
This file should always be kept under version control.
What is happening behind the scenes?
In Xcode, it:
[Creates or updates a workspace.][creating-a-workspace]
[Adds your project to the workspace if needed.][adding-projects-to-workspace]
[Adds the CocoaPods static library project to the workspace if needed.][adding-projects-to-workspace]
[Adds libPods.a to: targets => build phases => link with libraries.][adding-build-target-dependencies]
Adds the CocoaPods Xcode configuration file to your app’s project.
[Changes your app's target configurations to be based on CocoaPods's.][basing-target-configurations-on-xcconfig] (Expand the ‘To add a new build configuration…’ section of the linked page for a howto.)
Adds a build phase to copy resources from any pods you installed to your app bundle. i.e. a ‘Script build phase’ after all other build phases with the following:
Shell: /bin/sh
Script: ${SRCROOT}/Pods/PodsResources.sh
Note that steps 3 onwards are skipped if the CocoaPods static library is already in your project.
CocoaPods' goal is to improve discoverability of, and engagement in, third party
open-source libraries, by creating a more centralized ecosystem.
Common Misconceptions
1. “CocoaPods is not ready for prime-time yet.”
Correct. Version 1.0.0 will be the milestone where we feel confident that all
the basic requirements of an Objective-C dependency manager are fulfilled.
Once we reach the 1.0.0 milestone, we will, for the first time ever, contact
the community at large through mailing-lists such as cocoa-dev.
2. “CocoaPods doesn’t do X, so it’s unusable.”
First see point #1, then consider that unless you tell us about the missing
feature and why it is important, it won’t happen at all. We don’t scour Twitter
to look for work, so please file a
ticket, or, better yet, start a pull-request.
3. “CocoaPods doesn’t do dependency resolution.”
CocoaPods does in fact do dependency resolution, but it does not automatically
resolve conflicts. This means that when a conflict occurs, CocoaPods will
raise an error and leave conflict resolving up to the user. (The user can do
this by depending on a specific version of a common dependency before
requiring the dependencies that lead to the conflict.)
If you’re familiar with Ruby then you can compare the former (the current
CocoaPods style) to RubyGems’ style resolution and the latter (with conflict
resolving) to Bundler’s.
Adding conflict resolution to CocoaPods is on our TODO list and we will try to
work with the Bundler team to see if we can share their algorithm, but this
will be one of the last things we’ll work on. A feature like this will require
a stable basis and since we’re not there yet, working on it now would only make
working on the basics more complex than necessary.
Finally, while conflict resolving is a definite must-have, you should ask
yourself if you’re not using too many dependencies whenever you run into
conflicts, as this is in general a good indicator. See the link to a blog post
about this in #4.
4. “CocoaPods is bad for the community, because it makes it too easy for users to add many dependencies.”
This is akin to saying “guns kill people”, but everybody knows it’s really
people who kill people (and psychotic bears with
machetes).
Furthermore, this reasoning applies to basically any means of fetching code
(e.g. git) and as such is not a discussion worth having.
What is worth discussing, however, is informing the user to be responsible.
Ironically enough, the original author of CocoaPods is convinced using a lot of
dependencies is a really bad idea. For practical advice on how to deal with
this, you should read this blog post
by Manfred Stienstra.
5. “CocoaPods uses workspaces, which are considered user data. Why does it not use normal sub-projects?”
Since then, they have also added workspace files to each .xcodeproj document,
leading people to believe that a workspace is user data only. This is simply
incorrect and you should not ignore workspace documents any longer if you
were doing so.
Note that CocoaPods itself does not require the use of a workspace. If you
prefer to use sub-projects, you can do so by running pod install --no-integrate, which will leave integration into your project up to you as
you see fit.