Один наконечник, разные активы. Связки?

У меня есть приложение для iPhone, которое поставляется с разными оттенками кожи, с различными художественными активами и звуками, но с одним и тем же кодом.

У меня есть вещи, созданные с несколькими целями, но проблема, с которой я столкнулась, - это иметь другой набор файлов UIBuilder nib, по одному на просмотр для каждой цели, чтобы указать на правильное искусство для этого мишени.

Это немного расстраивает, потому что, если я вношу изменения в один файл nib, мне приходится вручную делать те же самые изменения, те же соединения и т.д. во всех других файлах nib. Я также поместил все активы с разными именами для разных скинов, поэтому они не сталкиваются в проекте. Итак, если у меня есть цели A и B, у меня есть a_main_menu.png, b_main_menu.png... a_FooViewController.xib, b_FooViewController.xib... и т.д.

Есть ли способ сделать файл nib, указывающий на активы с таким же именем, но находящиеся в... umm, разные пакеты? что для чего нужен пакет? Я могу себе представить, как в моем коде можно что-то сделать (возможно, поиск и замена A для B в nib перед загрузкой может даже быть достаточно хорошим), хотя я не пробовал, это уродливо.

Это была управляемая стратегия для моего первого набора приложений (хотя и далеко не оптимальная), но по мере того, как мои вещи становятся более сложными, это становится ДЕЙСТВИТЕЛЬНО трудным для того, чтобы синхронизировать мои файлы с разработчиками, и это просто не очень СУХОЙ способ Работа. Есть ли лучший способ в стороне от канава uibuilder и создания моих представлений в коде?

Было бы неплохо, если бы это сработало на уровне xcode/builder, поэтому строитель будет уважать мою текущую цель и покажет искусство для этой цели, пока я работаю... но я могу жить без этого, например, если я может выбрать текущий набор произведений искусства во время выполнения, и я смогу работать только с одним набором в построителе. Я мог бы также сделать это с помощью одного набора перьев, имея единственную цель и вручную заменяя все искусство перед тем, как строить, но это тоже не очень приятно.

Лучше всего было бы, если бы я мог смешивать две стратегии - например, если у меня есть одна цель, у которой есть один вид из нескольких, которые просто должны быть выложены по-другому... но это необязательно.

Я задаю правильный вопрос?

Спасибо!

Ответ 1

Один из способов сделать это - переместить все ваши произведения в отдельный пакет и динамически загружать его во время выполнения (вроде как "плагин для мультимедиа" ).

  • Создайте отдельный проект и выберите "Mac OS X/Framework и Library/Bundle". Назовите это, скажем, media.bundle.

  • Переместите все ваши работы в этот проект.

  • Чтобы сделать жизнь проще, добавьте дополнительный шаг "Запустите Script" к целевому копированию встроенного вывода из каталога сборки в подпапку под вашим основным проектом. Чтобы сделать это еще проще, добавьте медиа-пакет в качестве зависимого проекта в ваш основной проект, чтобы он автоматически перестраивался.

В вашем основном проекте вам понадобятся эти два метода. Вы можете сделать их статическими методами в классе BundleUtils:

+ (NSString *) bundleDirectoryFor:(NSString *) bundleName
{
 NSString* basePath = [[[NSBundle mainBundle] resourcePath]
     stringByAppendingPathComponent:[NSString
                                stringWithFormat:@"%@.bundle", bundleName]];
 return [[NSBundle bundleWithPath:basePath] resourcePath];
}

+ (NSString *) resourceInBundle:(NSString *)bundleName 
                       fileName:(NSString *)fileName
{
 NSString *bundlePath = [BundleUtils bundleDirectoryFor:bundleName];
 return [bundlePath stringByAppendingPathComponent:fileName];
}

Теперь каждый раз, когда вы хотите получить доступ к обложке в своем комплекте, вы можете получить путь к правильному файлу с помощью:

NSString* imageFile = [BundleUtils resourceInBundle:@"media.bundle" 
                                        fileName:@"image.jpg"];
UIImage* image = [UIImage imageNamed:imageFile];

Очевидно, что имя "media.bundle" можно заменить во время выполнения для другого, чтобы вы могли переключиться на другие пакеты на основе потребностей вашего приложения. Это также удобный способ поддержки загружаемого контента (скажем, как для платных надстроек).

Одно предостережение: предполагается, что вам нужно загружать изображения динамически во время выполнения через код. Но у вас также есть статические файлы NIB, в которые встроены медиа. Вам нужно выяснить, как заставить статический файл NIB использовать динамические методы для разрешения имен файлов мультимедиа. Один из способов - использовать MethodSwizzling и следить за файловыми путями с префиксом типа, скажем, "media: image.png", и перенаправить их на используйте методы BundleUtil.

Другой способ - сделать ваш макет с IB, а затем преобразовать его в код Obj-C, используя nib2objc, а затем заменить механизм связки плагинов.

Надеюсь, что это поможет.

Ответ 2

Предполагая, что для каждого приложения требуется только один скин за один раз, и что вы создаете несколько приложений с разными темами, я бы создал ветвь в своем исходном элементе управления, а затем заменил необходимые ресурсы. У вас есть ведущая ветвь со всеми активами по умолчанию, а затем вы объединяете изменения кода от мастера в ваши обработанные ветки, сохраняя все в синхронизации.

Git делает это очень просто.

Ответ 3

Я думаю, что лучший вариант - использовать что-то вроде git.

Если вы использовали git, вы можете иметь основную ветвь, которая содержит главный исходный код и логику, и иметь подвыборы, которые имеют разные наборы данных/изображений для каждого конкретного вкуса вашего приложения. В этом решении XCode даже не знал, что происходит.

Ответ 4

Я думаю, что это то, для чего предназначен viewDidLoad, для настройки большего количества здесь вы можете изменить путь к изображениям.

Ответ 5

Это работает для меня:

1 проект. 2 цели a, b. 2 папки изображений для a, b.

Контроллер .m и его файл nib для обеих целей.

Создайте отдельные папки файловой системы для изображений целей a и b.

Импортируйте одну папку изображений для таргетинга ( "добавить файлы в xy" → "добавить к целям a/b" ), а другая - к цели b. Убедитесь, что вы используете опцию "создавать группы для добавленных папок". Не выбирайте опцию "ссылки на папку".

Когда я создаю цель a, я получаю приложение с изображениями из папки a; когда я строю для b, он использует папку b для фото.