Подтвердить что ты не робот

Как настроить независимые наборы параметров времени выполнения в XCode

Мое приложение iPhone подключается к трем различным серверам, говорят: производство, постановка и тестирование. Существует множество значений конфигурации, которые приложение использует в зависимости от того, к какому серверу оно подключается, например, идентификатор приложения Facebook, ключ команды TestFlight и т.д.

Я хотел бы иметь все настройки в GIT и выбирать только ту конфигурацию, которую приложение должно использовать при компиляции или выпуске. Например, когда выбрано тестирование, Product → Run in Xcode запускает отладочную версию приложения, подключенного к тестированию, а Product → Archive создает файл IPA с версией выпуска, которая также подключается к тестированию.

Я не хочу создавать больше конфигураций сборки, чем отладку и выпуск (потому что это будет означать 6 различных комбинаций конфигураций сборки/конфигураций времени выполнения). Идеальное решение, как я понимаю, будет то, что у меня есть три схемы: производство, испытание и постановка, и каждая схема выбирает один из трех Info.plist файлов для использования с приложением. Это позволило бы мне не только определять различные параметры времени выполнения, но также разные версии приложений или идентификаторы пакетов в зависимости от внутреннего сервера. Но, похоже, я не могу настроить действие "Архив" другим способом, кроме выбора другой конфигурации сборки. Любые идеи, если это может быть достигнуто каким-либо образом?

Изменить: чтобы было немного понятнее, производство/подготовка/тестирование - это сервер, а не версия приложения для iOS. Приложение для iOS выпускается в двух версиях: отладка/выпуск. Другими словами, я могу захотеть запустить отладочную версию приложения, подключенного к производственному серверу, например, для отладки сбоя, вызванного возвращением JSON с этого сервера. Я мог бы назвать серверы как A, B и C для ясности.

4b9b3361

Ответ 1

Я бы предложил использовать разные цели сборки для каждой среды. Я успешно использовал эту модель раньше. В настройках вашего проекта вы можете дублировать текущую цель и изменять настройки сборки по мере необходимости. Там есть свойство Info.plist File, которое позволит вам изменить значение по умолчанию для этой цели.

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

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

Единственным недостатком в этом является то, что у вас больше работы, когда вы хотите обновлять профили подготовки.

Ответ 2

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

Сначала вы хотите настроить конфигурации на уровне проекта:

enter image description here

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

Далее вы можете определить несколько макросов для каждой конфигурации, которая будет передана компилятору. Затем вы можете проверить эти флаги во время компиляции. Найдите настройку сборки "Preprocessor flags" на целевом уровне:

enter image description here

Если вы развернете треугольник, вы можете определить разные значения для каждой из ваших конфигураций. Здесь вы можете определить макросы KEY=VALUE или просто KEY.

enter image description here

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

#ifdef DISABLE_FEATURE_X
    featureXButton.hidden = YES;
#endif

// ...

#if FOOBAR_VISIBLE == 0
    foobarView.hidden = YES;
#elif FOOBAR_VISIBLE == 1
    foorbarView.hidden = NO;
#else
    #error Invalid value for FOOBAR_VISIBLE
#endif

Вы также можете передать строковые значения, которые должны быть обернуты одинарными кавычками в настройке сборки, например. DEFAULT_LOCALIZATION_NAME='@"en"'.

Вы также можете настроить, какая конфигурация используется во время Debug и Archive time, используя редактор Schemes. Если вы выберете "Выполнить" или "Архив" в редакторе схем, вы можете выбрать соответствующую конфигурацию.

enter image description here

Если вам нужно параметризовать записи в файле Info.plist, вы можете определить их значение, используя настраиваемую настройку сборки. Добавьте настраиваемую настройку сборки для своей цели:

enter image description here

И затем дайте ему соответствующее значение для разных конфигураций:

enter image description here

Затем в файле Info.plist вы можете ссылаться на этот параметр:

enter image description here

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

  • Settings.bundle

Кроме того, в старых версиях Xcode без поддержки каталога каталогов вы не можете изменить следующие элементы:

  • Icon.png
  • Default.png

Они не могут быть явно определены в файле Info.plist или где-либо еще, что означает, что вам нужны разные цели для их изменения.

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

Ответ 3

Здесь гораздо проще, если соответствующие библиотеки позволяют устанавливать ключи в коде, что означает, что вы можете иметь производственное значение в вашем файле plist, но изменить их в своем AppDelegate (или в любом из файлов, в котором они сначала используются).

Работает с facebook, twitter и google sdk на данный момент.

Пример:

#ifdef DEBUG
  // Facebook
  [FBSettings setDefaultAppID:@"SandboxID"];
  // Fabric / TwitterKit - must be called above [Fabric with:@[TwitterKit]];
  [[Twitter sharedInstance] startWithConsumerKey:@"SandboxKey" consumerSecret:@"SandboxIDSecret"];
#endif

То же самое в Swift, просто используйте #if вместо #ifdef.

Примечание о Facebook. Это работало с версией 3 их SDK, я не уверен, что это возможно с более поздними версиями.

Ответ 4

Это, вероятно, очень низкоэффективная технология, но у меня просто есть метод apiURL() который возвращает URL API, который я хочу. У меня есть localhost, stage и production, и я просто раскомментирую тот, который хочу. До сих пор это работало хорошо для меня. Я только забыл переключить его обратно несколько раз. К сожалению.