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

Как определить, выполняется ли код в основном приложении или в расширении приложения?

Кто-нибудь знает, как вы определяете из своего кода, если вы работаете внутри расширения приложения?

У меня есть приложение, которое разделяет классы между приложением и расширением. Код приложения использует [UIApplication sharedApplication] но он не доступен из расширения, поэтому он не будет компилировать высказывание:

"sharedApplication" недоступно: недоступно iOS (расширение приложения)

Поэтому мне нужен способ обнаружить, что я нахожусь в расширении, и использовать альтернативу sharedApplication если это так.

4b9b3361

Ответ 1

Вы можете использовать макрос препроцессора:

В настройках проекта используйте раскрывающийся список в верхней панели, чтобы выбрать цель расширения: enter image description here

Тогда:

  • Нажмите Build Settings
  • Найти (или выполнить поиск) Preprocessor Macros под Apple LLVM 6.0 - Preprocessing
  • Добавьте TARGET_IS_EXTENSION или любое другое имя по вашему выбору в разделах отладки и выпуска.

Затем в вашем коде:

#ifndef TARGET_IS_EXTENSION // if it not defined
    // Do your calls to UIApplication
#endif

Ответ 2

Как Документация Apple говорит:

Когда вы создаете расширение на основе шаблона Xcode, вы получаете комплект расширения, который заканчивается на .appex.

Итак, мы можем использовать следующий код:

if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
    // this is an app extension
}

Ответ 3

Макрос препроцессора будет работать в основном, но не будет работать в общей библиотеке (например, cocoapods или shared frameworks).

В качестве альтернативы вы можете использовать следующий код.

@implementation ExtensionHelpers

+(BOOL) isAppExtension
{
    return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}

@end

Эта работа, проверяя пакет executablePath, поскольку только расширение приложения имеет расширение ".appex".

Ответ 4

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

Ответ 5

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

Ответ 6

Swift 5

let bundleUrl: URL = Bundle.main.bundleURL
let bundlePathExtension: String = bundleUrl.pathExtension
let isAppex: Bool = bundlePathExtension == "appex"

// 'true' when invoked inside the 'Extension process'
// 'false' when invoked inside the 'Main process'