Нельзя не упомянуть опубликованные ранее статьи по этой теме — введение в Cocoapods и краткое резюме по созданию своего pod'а.
Последняя указанная статья дала толчок в нужном направлении, но не хватало знаний для полного понимания поданной информации. Цель данной статьи — максимально подробно описать процесс создания и использования своего собственного CocoaPod'а, далее для краткости — «pod». Ну и упорядочить свои познания в данной области.
Введение
Ознакомившись с первой указанной статьей мы уже имеем на своём Mac установленный и готовый к бою CocoaPods, понимание что это такое и для чего нужно. Для чего нужен свой родной «pod» так же должно быть понятно.
На странице проекта малосодержательно описан общий принцип построения своего «pod»'а. Рекомендованная авторами структура каталогов для разработки «pod»'а выглядит следующим образом:
.
├── Classes
└── ios
└── osx
├── Resources
├── Project
└── Podfile
├── LICENSE
├── Readme.markdown
└── NAME.podspec
Что к чему:
- Classes — каталог, в подкаталогах которого находятся исходники вашего «pod»'а для iOS и/или OS X
- Resources — изображения, видео, прочие бинарники, Core Data модели и т.п.
- Project — проект, использующий ваш «pod», как правило — проект в котором показаны примеры использования вашего «pod»'а, крайне желательно с unit-тестами
- Podfile — в этом файле, как должно быть уже известно, указываются зависимости проекта от разнообразных «pod»'ов, в данном случае от создаваемого нашего
- Опускаем файлы, говорящие за себя своим названием
- NAME.podspec — спецификация создаваемого «pod»'а
Создаём «pod»-проект
Итак, начнём. На всякий случай проект-пример лежит на GitHub.
Создайте свой репозиторий на GitHub с именем, например, MyCustomPod.
Создадим наш «pod»-проект, для этого в терминале вводим следующее:
$ mkdir ~/Documents/PodSample
$ cd ~/Documents/PodSample
$ git init
$ git remote add origin https://github.com/username/MyCustomPod.git
$ touch LICENSE
$ git add LICENSE && git commit -m "License file"
$ git push -u origin master
$ mkdir Classes
Краткое описание происходящего.
Создаём локальный git репозиторий, привязываем его к GitHub, создаём и коммитим файл где будет описана схема лицензирования проекта и отправляем изменения на GutHub. Создаём каталог Classes в котором будут лежать исходники самого «pod»'а. Подкаталоги же Classes/ios и Classes/osx создавать не будем, т.к. ориентируемся пока только на одну платформу — iOS.
Создаём «spec»
И снова к теории. Каждый «pod» имеет свою спецификацию — «spec», которая описывает его метаданные: имя, версия, лицензия, зависимости от версии платформы, используемых фреймворков, других «pod»'ов, репозиторий исходников, использование ARC и т.д. Всё это записывают в файл NAME.podspec.
Файл .podspec создаётся разработчиком «pod»'а и размещается в специальном репозитории «spec»'ов. Существует основной репозиторий где и «живут» все доступные по-умолчанию «pod»'ы как, например, небезызвестный AFNetworking. Там же может появится и ваш полезный «pod». Так же существует возможность создать и использовать свой личный «specs»-репозиторий, доступ к которому регулируется лично вами.
Но вернёмся к началу. Чтобы создать свой .podspec достаточно в терминале ввести следующую команду:
$ pod spec create MyLibrary
В результате в текущем каталоге получим «spec»-шаблон в виде файла MyLibrary.podspec, в котором подробно расписано для чего нужен каждый параметр. Более детальное описание формата файла указано на wiki странице проекта.
Всем известно — лучшее обучение всегда строится на военном принципе «от простого к сложному», не будем и мы чураться канонов.
Для начала зададим номинальный набор параметров:
Pod::Spec.new do |s|
s.name = "MyLibrary"
s.version = "0.0.1"
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.source_files = 'Classes/*.{h,m}'
s.public_header_files = 'Classes/*.h'
s.framework = 'Foundation'
s.requires_arc = true
end
Пробежимся по строкам, требующим точного понимания происходящего:
- version — текущая версия нашего «pod»'а
- license — в мире, где уже полтыщи лет орудуют копирасты, крайне желательно указать тип лицензии вашего творчества
- author — а так же автора данного произведения
- platform — здесь мы указываем, что наш «pod» создан только для платформы iOS минимальной версии 7.0, альтернативно можно использовать параметр deployment_target:
s.ios.deployment_target = '7.0'
- source — указываем место, где находится проект нашего «pod»'а, нетрудно заметить, что в данном случае проект опубликован на GitHub и каждая версия проекта помечена соответствующим тэгом, где имя тэга совпадает с номером версии (чуть ниже будет более понятно что к чему)
- source_files — перечисляем исходные файлы нашего «pod»'а, относительно корневого каталога проекта
- public_header_files — заголовочные файлы «pod»'а, которые должны быть доступны использующему наш «pod» приложению
- framework — тут указывается фреймворк, который автоматически будет подключен в проект «Pods» при установке вашего «pod»'а
- requires_arc — сообщаем, что используется ARC
Если нужно указать несколько авторов или фреймворков — преобразуем имя параметра во множественное число, например, authors и перечисляем значения через запятую.
Если проект будет использоваться и для OS X то необходимо создать подкаталоги Classes/ios и Classes/osx, поправить значения параметров:
s.source_files = 'Classes/**/*.{h,m}'
s.public_header_files = 'Classes/**/*.h'
Удалить строку с параметром platform и добавить следующие параметры:
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.8'
Линтуем «spec»
Процесс линтовки заключается в проверке синтаксиса .podspec файла, наличия необходимых параметров, актуальности значений параметров и попытки скомпилировать наш «pod». Существует так называемая «быстрая» линтовка, где просто проверяется синтаксис .podspec файла и наличие обязательных параметров, при этом не происходит скачивание «pod»-репозитория и попыток его скомпилировать.
Записываем получившийся MyLibrary.specpod и сначала проводим «быструю» линтовку, используя ключ --quick:
$ pod spec lint ~/Documents/PodSample/MyLibrary.podspec --quick
В идеале должно отобразиться нечто вроде:
$ pod spec lint ~/Documents/PodSample/MyLibrary.podspec --quick
-> MyLibrary (0.0.1)
Analyzed 1 podspec.
MyLibrary.podspec passed validation.
В случае появления ошибок каждая ошибка достаточно внятно комментируется и исправление не доставляет проблем.
Далее коммитим наши изменения в git:
$ git add MyLibrary.podspec && git commit -m "Completed podspec file"
Для того, чтоб полная линтовка прошла успешно создадим пару пустых файлов (иначе увидим ошибку — "ERROR | [iOS] The `source_files` pattern did not match any file."):
$ touch Classes/AKClass.m
$ touch Classes/AKClass.h
$ git add Classes/AKClass.* && git commit -m "Empty files for successful lint"
Проставим тэг с номером текущей версии и опубликуем наш «pod» в GitHub:
$ git tag "0.0.1" && git push origin master --tags
Линтуем:
$ pod spec lint ~/Documents/PodSample/MyLibrary.podspec
Если всё правильно наблюдаем похожую картину:
$ pod spec lint ~/Documents/PodSample/MyLibrary.podspec
-> MyLibrary (0.0.1)
Analyzed 1 podspec.
MyLibrary.podspec passed validation.
Ура! Наш «pod»-проект настроен и не содержит ошибок.
Продолжение следует.
Запланировано:
Часть 2. Делим наш «pod» на модули. Используем чужой «pod» для разработки своего.
Часть 3. Публикация своего «pod»'а. Общий репозиторий и личный.
Автор: Adnako