- PVSM.RU - https://www.pvsm.ru -
Cocoapods [1] – это менеджер зависимостей библиотек в Xcode проектах. Я не буду рассказывать, как с его помощью подключить в проект уже существующую библиотеку, информации достаточно, в том числе и эта статья [2] на Хабре. Я расскажу что делать, если вы не нашли нужную вам библиотеку в списке [3], или, что ещё хуже, вы хотите создать свою библиотеку и, как вариант, не делать её доступной.
Для начала стоит посмотреть, какие возможности даёт нам Cocoapods, для подключения библиотеки в проект (через podfile):
pod 'Reachability'
pod 'AFNetworking/Reachability'
pod 'JSONKit', '~> 1.4'
Самый простой способ (он же основной), при этом можно указать привязку к конкретной версии и подключить не всю библиотеку, а только её часть (через subspec)
pod 'ZipKit', :podspec => 'ZipKit.podspec'
Можно использовать тогда, когда существующая Cocoapods спецификация вас каким-то образом не устраивает (например, в спецификации к библиотеке стоит iOS 6.1, а у вас в проекте Deployment target выставлен в 6.0). Сохраняем себе спецификацию, редактируем её под свои нужды, сохраняем в корень проекта – в результате у вас всё работает, и при этом нет необходимости добавлять потенциально вредные изменения в публичную спецификацию.
pod 'SuperLibrary', :path => 'Submodules/SuperLibrary'
Этот вариант уже интереснее, так как можно указать путь к совместному коду (subversion external, git submodule...). При таком способе файлы библиотеки включаются в проект со ссылками на этот путь, что позволяет нам редактировать библиотеку и сохранять измения в системе контроля версий. Более подробно вернёмся к этому позже
pod 'SuperLibrary', :git => 'git@bitbucket.org:bestcompany/SuperLibrary.git', :branch => 'development'
Основное отличие от предыдущего пункта в том, что редактировать исходный код библиотеки уже нельзя (технически можно, однако при установке зависимостей в проект будут просто добавлены копии файлов, которые никак не будут ссылаться на оригинал и будут переписаны на оригинальные файлы при последующем обновлении зависимостей)
Создать спецификацию просто:
pod spec create SuperLibrary
Открываем сгенерированный файл, заполняем сгенерированные разделы, читая комментарии, при затруднениях обращаемся к документации [4].
И здесь стоит вспомнить про такой механизм, как модули библиотеки (subspec). В кратце, разбиваем нашу библиотеку на некоторые логические модули (в том числе связанные между собой), описываем ресурсы, исходные коды, зависимости по-отдельности, например:
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
Доступ к модулю осуществляется через MasterSpec/Subspec, одни модули внутри могут зависеть от других внутри одной спецификации, допускается многоуровневая вложенность. Осталось указать модуль, который будет подключен по умолчанию, например
s.default_subspec = 'Controllers'
И всё, библиотеку можно подключать по частям, например только сетевое ядро, не затрагивая ресурсы и Unit-тесты.
Несколько советов:
Схема базы данных (*.xcdatamodeld и иже с ними) это ресурс а не исходный код, с недавней версии cocoapods подключается нормально, в том числе вместе с версиями схемы.
Зависимости своей библиотеки от других желательно прописывать без привязки к конкректной версии (за исключением, например, Facebook-iOS-SDK, API которой меняется слишком часто).
Библиотеки подключать знаем как, создавать спецификацию умеем, идея версий библиотек нам нравится, но делиться библиотеками не будем. Весьма частая ситуация в маленьких и больших компаниях, есть много проектов, на них используется совместный код, хорошо бы их оформить как библиотеки и работать с версиями так же просто, как и с обычными cocoapods библиотеками. И тут на помощь приходит приватные репозитории. Что нам для этого потребуется:
pod repo add Private-Cocoapods git@bitbucket.org:bestcompany/cocoapods-specs.git
Осталось дело за малым, создаём в корне этого репозитория папку с именем библиотеки, в ней создаём папку с версией библиотеки, куда уже помещаем непосредственно саму спецификацию.
Всё, осталось отправить эти изменения на репозиторий и последующие команды pod install (или pod update) будут работать с нашей библиотекой так же, как и с официальной, то есть подключать pod можно будет просто по имени библиотеки.
И один из сценариев, как с этим можно успешно работать. Предпосылка: ведётся разработка нескольких продуктов (одновременно или нет, не важно), в приложениях есть совместно используемый код (библиотеки), разработка каждой библиотеки ведётся в собственной ветке репозитория.
Итак, нам надо, чтобы в корне каждой библиотеки лежал актуальный podspec файл, версия в podspec файле идёт с постфиксом dev, параметр source ссылается на текущую ветку, например:
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"}
Таким образом, при подключении этой версии непосредственно из репозитория, мы будем иметь пометку dev, говорящую о том, что версия не готова. После тестирования этот библиотеки создаём tag с именем версии (проверить версию, и, если необходимо, поднять минорную/мажорную версию), копируем podspec файл в наш собственный репозиторий спецификаций, убирая приставку dev из версии и указав конкретный таг в репозитории, который мы только что создали:
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" }
Всё, осталось в репозитории библиотеки выставить версию на один больше не убирая постфикс dev (1.1.1-dev в нашем случае) и отправить все изменения в репозиторий.
Разработка, обычно, это процесс бесконечный, и необходимость править библиотеки возникает очень часто. Для таких случаев можно всегда хранить ссылку на текущую версию библиотеки в репозитории через сабмодуль в Git (external в Subversion). При этом в podfile конкретного продукта всегда указана стабильная версия (podspec хранится на нашем репозитории спецификаций), но рядом закоментированная строчка на текущую версию:
#pod 'SuperLibrary', :path => 'Submodules/SuperLibrary'
pod 'SuperLibrary'
В случае необходимости внести изменения в библиотеку, убираем комментарий со строчки, обновляем библиотеку до последней версии в репозитории, делаем pod update в консоли и всё, можно смело изменять и тестировать. Перед подготовкой приложения в публикацию стоит зафиксировать все версии библиотек (то есть создать новые версии для всех изменённых библиотек и подключить их из нашего репозитория спецификаций). Всегда проверяйте podfile.lock на то, какие версии библиотек используются, наш постфикс -dev очень помогает определить, что версия библиотеки может быть не протестирована.
И да, делать pod update как часть процесса сборки приложения явно не стоит (по-крайней мере на стадии подготовки версии к релизу, так как из-за обновления библиотеки обязательно что-то перестанет работать в последний момент).
P.S. Cocoapods обновляется постоянно, исправляются ошибки, добавляются новые возможности (и новые ошибки). Если у вас что-то перестало работать (а такое случается), не поленитесь, пожалуйста, найти причину, и, если дело именно в cocoapods, дайте знать [5] разработчикам.
Автор: pcholberg
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/objective-c/45476
Ссылки в тексте:
[1] Cocoapods: http://cocoapods.org/
[2] эта статья: http://habrahabr.ru/company/luxoft/blog/149631/
[3] в списке: https://github.com/CocoaPods/Specs
[4] документации: http://docs.cocoapods.org/specification.html
[5] дайте знать: https://github.com/CocoaPods/CocoaPods/issues
[6] Источник: http://habrahabr.ru/post/196736/
Нажмите здесь для печати.