Как определить, выполняется ли код в Основном приложении или в Целевом расширении приложения?
-
21-12-2019 - |
Вопрос
Кто-нибудь знает, как вы определяете из своего кода, работаете ли вы внутри расширения приложения?
У меня есть приложение, которое разделяет классы между приложением и расширением.Код приложения использует [UIApplication sharedApplication]
но это недоступно из расширения, поэтому оно не будет компилироваться со словами:
"Совместное приложение" недоступно:недоступно для iOS (расширение приложения)
Итак, мне нужен способ определить, что я нахожусь в расширении, и использовать альтернативу sharedApplication
если это так.
Решение
Вы можете использовать предварительнопроцессорный макрос:
В настройках проекта используйте раскрывающийся список в топбаре, чтобы выбрать целью расширения:
Тогда:
- Нажмите
Build Settings
- Найти (или поиск)
Preprocessor Macros
подApple LLVM 6.0 - Preprocessing
- Добавить
TARGET_IS_EXTENSION
или любое другое имя по вашему выбору в разделах отладки, так и в разделах.
Тогда в вашем коде:
#ifndef TARGET_IS_EXTENSION // if it's not defined
// Do your calls to UIApplication
#endif
. Другие советы
как Документация Apple говорит: .
При создании расширения на основе шаблона Xcode вы получаете расслоение расширения, которое заканчивается в .appex.
Итак, мы можем использовать следующий код:
if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
// this is an app extension
}
. Препроцессорный макрос будет работать в основном, но не будет работать в общей библиотеке (например, cocoapod или общие рамки).
В качестве альтернативы вы можете использовать следующий код.
@implementation ExtensionHelpers
+(BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}
@end
.
Эта работа, проверив ExecutablePath Bundle DixutablePath, как только расширение приложения имеет расширение «.appex».
Вы можете добавить макрос препроцессора к целевому расширению, а затем проверить с помощью #ifdef
внутри вашего класса.
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`
. Для моей общей библиотеки я создал отдельную цель флаг расширения приложений ВОЗ, устанавливается на да, и использовал Preprocessor Macro в настройках сборки для этой конкретной цели.