Как определить, выполняется ли код в основном приложении или в расширении приложения?
Кто-нибудь знает, как вы определяете из своего кода, если вы работаете внутри расширения приложения?
У меня есть приложение, которое разделяет классы между приложением и расширением. Код приложения использует [UIApplication sharedApplication]
но он не доступен из расширения, поэтому он не будет компилировать высказывание:
"sharedApplication" недоступно: недоступно iOS (расширение приложения)
Поэтому мне нужен способ обнаружить, что я нахожусь в расширении, и использовать альтернативу sharedApplication
если это так.
Ответы
Ответ 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'