- Базовое самостоятельное приложение (продукт)
- Приложение для vendor-a на основе базового (экстеншен)
- переопределение локализации
- переопределение графических ресурсов
- переопределение сторибордов/ксибов/реализаций сервисов-классов
-
Локализация. Через обычные макросы
NSLocalizedString
илиNSLocalizedStringFromTable
. Локализацию желательно разбивать на логические модули, не держать все в одном огромномLocalizable.strings
. В экстеншене потом будет проще. -
Графика. Обычный способ
[UIImage imageWithName:]
, без указаний бандлов. ВIB
также, просто имена ресурсов. -
Сториборды/ксибы/реализации сервисов-классов. Есть специальный plist с сконфигом (аля spring), там указаны явные реализации для сервисов/классов, константы, переопределения сторибордов/ксибов. При старте приложения грузим конфиг, если это экстеншен, то базовый конфиг мержится с конфигом экстеншена. Потом инстанцируются глобальные сервисы/провайдеры. Сториборды бъются логически по сценам (1-3 контроллера), чтобы в экстеншенах можно было заменить часть функционала. Все названия должны быть с префиксом проекта. При инстанцировании
контроллеров/вьюх/классов с бизнес логикой
используются специальные провайдеры, которые по имени класса(или протокола) отдадут нужную реализацию. -
Файл проекта. Настройки вынесены в
*.xcconfig
файлы. Они позволяют при создании экстеншена упростить перенос настроек, сделать переопределения.
- отдельная папка для кода
modules
- на диск выгружается с именемapp
- отдельная папка для файла проекта (файл проекта не в папке с кодом)
- папка
project-all
- там скрипт для выгрузки исходников над диск + подтягивание зависимостей. - папка
thirdparties
. которая на картинке - она не подsvn
. Там зависимости (фрамеворки/либы), которые мы не будем сами менять. От примененияCocoaPods
отказались по своим причинам (сперва использовали активно).
- чтобы работал дебаг по коду продукта
- чтобы можно было из экстеншена вносить изменения в продукт (добавлять-удалять файлы, управлять таргетами). Не держать два проекта открытыми, типа вначале вносишь изменения в продукт, коммитишь, а в экстеншене подтягиваешь изменения из репозитория и потом вручную удаляешь-добавляешь файлы, назначаешь таргеты (кто использовал mogenerator, тот поймет).
- в репозитории структура идентична продукту. Папка
modules
выгружается на диск с именем экстеншена. - Классы, файлы UI и прочее, создаются с префиксом экстеншена.
- файл проекта для экстеншена и продукта находятся на одном уровне. В итоге у них единый
$(SRCROOT)
- для скриптов это очень полезно (ради этого и исключили их из папки исходников) - при выгрузке экстеншена создается папка
build
(не подsvn
) и в нейlocalizations.bundle
(не включается в таргет) иresources.xcassets (включается в таргет)
. Они добавлены в проекта экстеншена и используются для сборки. - на картинке ниже показан проект экстеншена в
xcode
. Продукт вложен в экстеншен - так получаем доступ с таргетам продукта и можем менять продукт.
- код продукта собирается как статическая либа и линкуется с экстеншеном (в либу не включаются зависимости, они напрямую включены в таргет экстеншена)
- сториборды/ксибы продукта собираются в отдельный бандл (плюс в том, что
xcode
их сам компилирует в*.nib
и*.storyboardc
) и потом скриптом копируются в кореньExtName.app
. - НЕ графические ресурсы (например, всякие
*.plist
файлы) и файлыcoredata
из продукта собираются в свой бандл и копируются вExtName.app
. - Графические ресурсы из продукта, перед
Compile sources
-фазой, копируются во вспомогательныйresources.xcassets
. Потом туда же копируются ресурсы из экстеншена. Файлы с одинаковыми именами заменяют друг друга. Так достигается цель переопределение графики. - Локализация из продукта копируется во вспомогательный бандл
localizations.bundle
, затем скрипт ищет совпадающие имена файлов в экстеншене и продукте и делает мерж файлов локализации (скрипт простейший - стандартная osx утилитаjoin
вам в помощь). Не совпадающие файлы из экстеншена добавляет в бандл без мержа. Затем компилит локализацию черезplutil -convert binary1 -- "<path_to_file>"
. Далее все из этого бандла копируется вExtName.app