📜 ⬆️ ⬇️

Xcode: manage dependencies of your own libraries in projects. Cocoapods advanced

Cocoapods is a library dependency manager for Xcode projects. I will not tell how with its help to connect already existing library in the project, there is enough information, including this article on Habré. I'll tell you what to do if you did not find the library you need in the list , or, even worse, you want to create your own library and, alternatively, do not make it available.

Part I: we connect libraries through podfile

First of all, you should see what features Cocoapods gives us to connect the library to the project (via podfile):

  1. Connect the library from the list of supported:
    pod 'Reachability' pod 'AFNetworking/Reachability' pod 'JSONKit', '~> 1.4' 
    The easiest way (it is the main one), while you can specify a binding to a specific version and connect not the entire library, but only a part of it (via subspec)
    ')
  2. Connect the library, but specify the path to the specification.
     pod 'ZipKit', :podspec => 'ZipKit.podspec' 
    You can use it when the existing Cocoapods specification does not suit you in any way (for example, the library specification is iOS 6.1, and your Deployment target is set to 6.0). We keep the specification, edit it to fit our needs, save it to the root of the project - as a result, everything works for you, and there is no need to add potentially harmful changes to the public specification.

  3. Connect the library by local path (along with the specification):
     pod 'SuperLibrary', :path => 'Submodules/SuperLibrary' 
    This option is more interesting because you can specify the path to the joint code (subversion external, git submodule ...). With this method, the library files are included in the project with links to this path, which allows us to edit the library and save changes in the version control system. More on this later.

  4. Connect the library (along with the specification) located in the version control system, or simply by clicking the archive link:
     pod 'SuperLibrary', :git => 'git@bitbucket.org:bestcompany/SuperLibrary.git', :branch => 'development' 
    The main difference from the previous paragraph is that the library source code can no longer be edited (technically possible, however, when installing dependencies, copies of files that will not refer to the original and will be copied to the original files will be added to the project upon subsequent update of dependencies)


Part II: we write the specification to own library - "how to send 2 bytes"

Creating a specification is simple:
 pod spec create SuperLibrary 
Open the generated file, fill in the generated sections, reading the comments, in case of difficulties, refer to the documentation .
And here it is worth remembering about such a mechanism as library modules (subspec). In short, we divide our library into some logical modules (including related ones), describe resources, source codes, dependencies separately, for example:
 s.subspec 'Data' do |ds| ds.source_files = 'Data/*.{h,m}', 'Data/Categories/*.{h,m}', 'Data/Objects/*.{h,m}' ds.resources = 'Data/SuperLibrary.xcdatamodeld' ds.dependency 'MagicalRecord' ds.dependency 'SuperLibrary/Resources' end 
Access to the module is through MasterSpec / Subspec, some modules inside can depend on others inside one specification, multi-level nesting is allowed. It remains to specify the module that will be connected by default, for example
 s.default_subspec = 'Controllers' 
And that's all, the library can be connected in parts, for example, only the network core, without affecting the resources and Unit tests.
Some tips:
The database schema (* .xcdatamodeld and others like it) is a resource and not the source code, with the recent version of cocoapods it connects normally, including with the versions of the schema.
It is desirable to prescribe the dependencies of your library on others without being tied to a specific version (except, for example, the Facebook-iOS-SDK, whose API changes too often).

Part III: your repository of specifications "with chess and poetess"

We know how to connect libraries, we know how to create a specification, we like the idea of ​​library versions, but we will not share libraries. A very common situation in small and large companies, there are many projects, they use joint code, it would be good to arrange them as libraries and work with versions as easy as with regular cocoapods libraries. And here private repositories come to the rescue. What we need for this:
  1. We create a new repository for specifications, which will be available to your team. The bad news is that only git is supported for the specification repository. (The good news is that git should only have a specification repository, the libraries themselves will still be accessible via git / svn or even through the usual link to the archive). Add it to cocoapods with a simple command from the console:
     pod repo add Private-Cocoapods git@bitbucket.org:bestcompany/cocoapods-specs.git 
    It remains the case for small, create in the root of this repository a folder with the name of the library, in it we create a folder with the library version, where we already place the specification itself.

    All that remains is to send these changes to the repository and subsequent pod install (or pod update) commands will work with our library in the same way as the official one, that is, you can connect the pod simply by the name of the library.


Part IV: We connect everything together, or how can we build the development process

And one of the scenarios of how to work with it successfully. Prerequisite: several products are being developed (at the same time or not, it doesn’t matter), applications have shared code (libraries), each library is developed in its own repository branch.
So, we need to have the actual podspec file in the root of each library, the version in the podspec file comes with the dev postfix, the source parameter refers to the current branch, for example:
 Pod::Spec.new do |s| s.name = "SuperLibrary" s.version = "1.0.5-dev" s.source = { :git => "ssh://git@bitbucket.org:bestcompany/my-super-library.git"} 
Thus, when connecting this version directly from the repository, we will have the dev mark indicating that the version is not ready. After testing this library, create a tag with the version name (check the version, and, if necessary, raise the minor / major version), copy the podspec file into our own specification repository, remove the dev prefix from the version and specify the specific tag in the repository that we just created:
 Pod::Spec.new do |s| s.name = "SuperLibrary" s.version = "1.1.0" s.source = { :git => "ssh://git@bitbucket.org:bestcompany/my-super-library.git", :tag => "SuperLibrary_v1.1.0" } 
All that is left in the library repository is to set the version to one no longer removing the dev postfix (1.1.1-dev in our case) and send all changes to the repository.
Development, usually, is an endless process, and the need to edit libraries arises very often. For such cases, you can always store a link to the current version of the library in the repository via the submodule in Git (external in Subversion). At the same time, in the podfile of a specific product there is always a stable version (podspec is stored in our specification repository), but the commented line next to the current version is next:
  #pod 'SuperLibrary', :path => 'Submodules/SuperLibrary' pod 'SuperLibrary' 
If necessary, make changes to the library, remove the comment from the line, update the library to the latest version in the repository, do the pod update in the console and everything, you can safely change and test. Before preparing an application for publication, it is worth fixing all versions of libraries (that is, creating new versions for all modified libraries and connecting them from our specification repository). Always check podfile.lock for which versions of libraries are used; our post -fix -dev helps a lot to determine that the version of the library may not be tested.
And yes, it is obviously not worth doing pod update as part of the application build process (at least at the stage of preparing the release version, because of the library update, something will definitely stop working at the last moment).

PS Cocoapods is constantly updated, bugs are fixed, new features are added (and new bugs). If something has stopped working for you (and this happens), do not be lazy, please find the reason, and if it is in cocoapods, let the developers know .

Source: https://habr.com/ru/post/196736/


All Articles