Como detectar se o código está em execução no aplicativo principal ou no destino da extensão de aplicativo?
-
21-12-2019 - |
Pergunta
Alguém sabe como você detecta no seu código se está executando dentro de uma extensão de aplicativo?
Tenho um aplicativo que compartilha classes entre um aplicativo e uma extensão.O código do aplicativo usa [UIApplication sharedApplication]
mas isso não está disponível em uma extensão, portanto não será compilado dizendo:
'sharedApplication' não está disponível:não disponível iOS (extensão de aplicativo)
Então preciso de uma maneira de detectar que estou na extensão e usar uma alternativa para sharedApplication
se for esse o caso.
Solução
Você pode usar uma macro de pré-processador:
Nas configurações do projeto, use o menu suspenso na barra superior para selecionar o destino da extensão:
Então:
- Clique
Build Settings
- Encontre (ou pesquise)
Preprocessor Macros
sobApple LLVM 6.0 - Preprocessing
- Adicionar
TARGET_IS_EXTENSION
ou qualquer outro nome de sua escolha nas seções de depuração e lançamento.
Então no seu código:
#ifndef TARGET_IS_EXTENSION // if it's not defined
// Do your calls to UIApplication
#endif
Outras dicas
Como Documentação da Apple diz:
Ao construir uma extensão baseada em um modelo Xcode, você obtém um pacote de extensão que termina em .appex.
Então, podemos usar o seguinte código:
if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) {
// this is an app extension
}
A macro do pré-processador funcionará principalmente, mas não funcionará na biblioteca compartilhada (por exemplo,cocoapods ou frameworks compartilhados).
Alternativamente, você pode usar o seguinte código.
@implementation ExtensionHelpers
+(BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:@".appex/"];
}
@end
Isso funciona verificando o pacote executablePath, pois apenas a extensão de aplicativo possui a extensão ".appex".
Você pode adicionar uma macro de pré-processador no destino da extensão e depois verificar com um #ifdef
dentro da sua aula.
Rápido 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`
Para minha biblioteca compartilhada, criei um destino separado cujo sinalizador de extensões de aplicativo está definido como sim e usei macros de pré-processador nas configurações de compilação para esse destino específico.