Part 2. We divide our "pod" into modules. We use someone else's “pod” to develop our own
Introduction
Continuing to develop the “pod” at some point, it comes to the understanding that the project is getting large and
Test project
Developing a “pod” in itself is at least strange. Usually its development is carried out in the context of a project. And even better, when a special project is being developed for the development of “pod”, it is covered with tests and with useful examples of use in the code. Let's create our test project “Single View Application” in the ~ / Documents / PodSample / Project directory . Then connect to it our "pod". To do this, create a Podfile file in the same directory . The result should look something like this:
Fill the Podfile :
platform :ios, '7.0'
pod 'MyLibrary', :path => '~/Documents/PodSample/MyLibrary.podspec'
Being the developer of “pod”, we can simplify our life and, after the name, explicitly indicate the path to the specification - the .podspec file . As a result, the installer will not get into the spec repositories, but will take the explicitly specified specification on the specified path. In principle, you can omit the file name MyLibrary.podspec - just specify the directory where the specification file for your “pod” is located, and the installer will find it. Also, nothing prevents the use of relative paths, for example:
platform :ios, '7.0'
pod 'MyLibrary', :path => '..'
Next, close Xcode, or at least the test project MyPodExample.xcodeproj .
Install our "pod":
$ cd ~/Documents/PodSample/Project/
$ pod install
Analyzing dependencies
Fetching podspec for `MyLibrary` from `~/Documents/PodSample/MyLibrary.podspec`
Downloading dependencies
Using MyLibrary (0.0.1)
Generating Pods project
Integrating client project
The installer generates a “workspace” for us, where he adds a test project and a new “Pods” project. Open the workspace MyPodExample.xcworkspace and observe something similar:
Select modules
Suppose our useful “pod” is already able to connect to the server, process JSON and store some data in its internal storage. Create a set of classes and declare a few methods in their public interfaces. The result is on GitHub with the tag mixed .
The separation of “pod” into modules takes place in two stages. First, the code is put in order, for which we distribute various entities in our own files. Then we update “spec” - we describe the resulting modules in “subspec” blocks and assign their dependencies to each other with the “dependency” parameter:
Pod::Spec.new do |s|
s.name = "MyLibrary"
s.version = "0.0.2"
s.summary = "Example of creating own pod."
s.homepage = "https://github.com/username/MyCustomPod"
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { "Username" => "username@mail.domain" }
s.platform = :ios, 7.0
s.source = { :git => "https://github.com/username/MyCustomPod.git", :tag => s.version.to_s }
s.framework = 'Foundation'
s.requires_arc = true
s.default_subspec = 'Core' # Модуль по умолчанию называется Core
s.subspec 'Core' do |core|
core.source_files = 'Classes/AKClass.{h,m}'
core.public_header_files = 'Classes/*.h'
core.dependency 'MyLibrary/Connection'
core.dependency 'MyLibrary/Provider'
end
s.subspec 'Provider' do |provider|
provider.source_files = 'Classes/AKProvider.{h,m}'
provider.frameworks = 'MapKit', 'CoreData' # Добавлены зависимости от фрэймворков
provider.platform = :ios, 5.0 # Этот модуль может запускаться и на iOS 5.0
end
s.subspec 'AccessToken' do |access_token|
access_token.source_files = 'Classes/AKAccessToken.{h,m}'
access_token.libraries = 'xml2' # Зависимость от библиотеки
access_token.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' } # Где искать заголовочные файлы
end
s.subspec 'Parser' do |parser|
parser.source_files = 'Classes/AKParser.{h,m}'
end
s.subspec 'Storage' do |storage|
storage.source_files = 'Classes/AKStorage.{h,m}'
storage.dependency 'MyLibrary/AccessToken'
end
s.subspec 'Connection' do |connection|
connection.source_files = 'Classes/AKConnection.{h,m}'
connection.dependency 'MyLibrary/Storage'
connection.dependency 'MyLibrary/Parser'
end
end
For the “Provider” module, we indicate the need to connect two frameworks - “MapKit” and “CoreData”. And for the AccessToken module, you need to connect the xml2 library, look for the header files at the specified path: $ (SDKROOT) / usr / include / libxml2
They say that from version CocoaPods v0.17 the modules no longer implicitly inherit the value source_files at the base "spec". To return this opportunity it is necessary to get a “Core” module which includes the basic source code needed for the modules being created.
It is also possible to break modules into submodules:
…
s.subspec 'Connection' do |сonnection|
сonnection.source_files = 'Classes/AKConnection.{h,m}'
сonnection.dependency 'MyLibrary/Storage'
сonnection.dependency 'MyLibrary/Parser'
сonnection.subspec 'Cache' do |cache|
cache.source_files = 'Classes/AKCache/*.{h,m}'
end
end
…
You can also specify the platform and its version on which the module can work. In this case, we indicated that the Provider module will start even on "iOS 5.0".
Check the syntax:
$ pod spec lint ~/Documents/PodSample/MyLibrary.podspec --quick
-> MyLibrary (0.0.2)
Analyzed 1 podspec.
MyLibrary.podspec passed validation.
And commit the changes to git, put the tag and send it to GitHub:
$ git add MyLibrary.podspec && git commit -m "Spec sliced on subspecs"
$ git add -A && git commit -m "Sliced code"
$ git tag "0.0.2"
$ git push origin master --tags
Check the whole project:
$ pod spec lint ~/Documents/PodSample/MyLibrary.podspec
-> MyLibrary (0.0.2)
Analyzed 1 podspec.
MyLibrary.podspec passed validation.
Module usage
To use only the necessary modules, it is enough to list them in the Podfile :
platform :ios, '7.0'
pod 'MyLibrary/Storage'
pod 'MyLibrary/Parser'
If you do not specify a single module:
platform :ios, '7.0'
pod 'MyLibrary'
then pod install will install the sources of all modules. If in this case it is only necessary to install the source code for the “Core” module, then in “spec” it is indicated its name in the parameter “default_subspec” - see the example above.
We indicate in our Podfile the dependence of the test project on the Provider module and at the same time indicate the version we need now - 0.0.2:
platform :ios, '7.0'
pod 'MyLibrary/Provider', :path => '..'
pod 'MyLibrary/Connection', :path => '..'
And update the project dependencies:
$ cd ~/Documents/PodSample/Project/
$ pod update
Analyzing dependencies
Fetching podspec for `MyLibrary` from `..`
Fetching podspec for `MyLibrary` from `..`
Downloading dependencies
Installing MyLibrary (0.0.2)
Generating Pods project
Integrating client project
Connecting a third-party pod
Sometimes it happens that the development of “pod” 'comes to the point where you want to
Pod::Spec.new do |s|
s.name = "MyLibrary"
s.version = "0.0.3"
s.summary = "Example of creating own pod."
s.homepage = "https://github.com/username/MyCustomPod"
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { "Username" => "username@mail.domain" }
s.platform = :ios, 7.0
s.source = { :git => "https://github.com/username/MyCustomPod.git", :tag => s.version.to_s }
s.framework = 'Foundation'
s.requires_arc = true
s.default_subspec = 'Core' # Модуль по умолчанию называется Core
s.subspec 'Core' do |core|
core.source_files = 'Classes/AKClass.{h,m}'
core.public_header_files = 'Classes/*.h'
core.dependency 'MyLibrary/Connection'
core.dependency 'MyLibrary/Provider'
end
s.subspec 'Provider' do |provider|
provider.source_files = 'Classes/AKProvider.{h,m}'
provider.frameworks = 'MapKit', 'CoreData' # Добавлены зависимости от фрэймворков
provider.platform = :ios, 5.0 # Этот модуль может запускаться и на iOS 5.0
end
s.subspec 'AccessToken' do |access_token|
access_token.source_files = 'Classes/AKAccessToken.{h,m}'
access_token.libraries = 'xml2' # Зависимость от библиотеки
access_token.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' } # Где искать заголовочные файлы
end
s.subspec 'Parser' do |parser|
parser.source_files = 'Classes/AKParser.{h,m}'
end
s.subspec 'Storage' do |storage|
storage.source_files = 'Classes/AKStorage.{h,m}'
storage.dependency 'MyLibrary/AccessToken'
end
s.subspec 'Connection' do |connection|
connection.source_files = 'Classes/AKConnection.{h,m}'
connection.dependency 'MyLibrary/Storage'
connection.dependency 'MyLibrary/Parser'
connection.dependency 'AFNetworking' # Добавлена зависимость от внешнего "pod"'а
end
end
Integration may cause problems with versions of platforms used by you and external pods. Having successfully solved them, we update the dependencies (it is highly desirable when the Xcode or project is closed):
$ cd ~/Documents/PodSample/Project/
$ pod update
Analyzing dependencies
Fetching podspec for `MyLibrary` from `..`
Fetching podspec for `MyLibrary` from `..`
Downloading dependencies
Installing AFNetworking (2.0.1)
Installing MyLibrary (0.0.3)
Generating Pods project
Integrating client project
The necessary “pods” are downloaded and connected, the workspace is configured. Now you can use the power of all other
To be continued.
Planned:
Part 3. Publishing your “pod” a. Shared repository and personal.