ios - plugin - ionic3 statusbar
Detectar se o aplicativo está sendo construído para dispositivo ou simulador no Swift (11)
Atualização 30/01/19
Embora essa resposta possa funcionar, a solução recomendada para uma verificação estática (conforme esclarecido por vários engenheiros da Apple) é definir um sinalizador de compilador personalizado destinado a Simuladores do iOS. Para instruções detalhadas sobre como fazer isso, veja a resposta do @ mbelsky .
Resposta original
Se você precisar de uma verificação estática (por exemplo, não um tempo de execução if / else) você não pode detectar o simulador diretamente, mas você pode detectar o iOS em uma arquitetura de desktop como segue
#if (arch(i386) || arch(x86_64)) && os(iOS)
...
#endif
Após a versão Swift 4.1
O uso mais recente, agora diretamente para todos em uma condição para todos os tipos de simuladores, precisa aplicar apenas uma condição -
#if targetEnvironment(simulator)
// your simulator code
#else
// your real device code
#endif
Para mais esclarecimentos, você pode verificar a proposta Swift SE-0190
Para versão mais antiga -
Claramente, isso é falso em um dispositivo, mas retorna true para o iOS Simulator, conforme especificado na documentation :
A configuração de compilação arch (i386) retorna true quando o código é compilado para o simulador iOS de 32 bits.
Se você está desenvolvendo para um simulador diferente do iOS, você pode simplesmente variar o parâmetro os
: por exemplo
Detectar o simulador watchOS
#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif
Detectar o simulador tvOS
#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif
Ou, ainda, detectar qualquer simulador
#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif
Se, em vez disso, estiver ok com uma verificação de tempo de execução, você poderá inspecionar a variável TARGET_OS_SIMULATOR
(ou TARGET_IPHONE_SIMULATOR
no iOS 8 e abaixo), que é válida em um simulador.
Observe que isso é diferente e um pouco mais limitado do que usar um sinalizador de pré-processador. Por exemplo, você não poderá usá-lo no lugar onde um if/else
é sintaticamente inválido (por exemplo, fora dos escopos de funções).
Digamos, por exemplo, que você queira ter importações diferentes no dispositivo e no simulador. Isso é impossível com uma verificação dinâmica, enquanto é trivial com uma verificação estática.
#if (arch(i386) || arch(x86_64)) && os(iOS)
import Foo
#else
import Bar
#endif
Além disso, como o sinalizador é substituído por 0
ou 1
pelo pré-processador swift, se você usá-lo diretamente em uma expressão if/else
o compilador emitirá um aviso sobre o código inacessível.
Para contornar esse aviso, consulte uma das outras respostas.
Em Objective-C, podemos saber se um aplicativo está sendo construído para dispositivo ou simulador usando macros:
#if TARGET_IPHONE_SIMULATOR
// Simulator
#else
// Device
#endif
Estas são macros de tempo de compilação e não estão disponíveis no tempo de execução.
Como posso conseguir o mesmo no Swift? Eu pesquisei o estouro de pilha, dei uma olhada nos documentos e não consegui descobrir.
Swift 4
Agora você pode usar targetEnvironment(simulator)
como um argumento.
#if targetEnvironment(simulator)
// Simulator
#else
// Device
#endif
Atualizado para o Xcode 9.3
Deixe-me esclarecer algumas coisas aqui:
-
TARGET_OS_SIMULATOR
não está definido no código Swift em muitos casos; você pode acidentalmente ser importado devido a um cabeçalho de bridging, mas isso é frágil e não é suportado. Também nem é possível em frameworks. É por isso que algumas pessoas estão confusas sobre se isso funciona no Swift. - Eu recomendo fortemente contra o uso da arquitetura como um substituto para o simulador.
Para executar verificações dinâmicas:
Verificando ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
está perfeitamente bem.
Você também pode obter o modelo subjacente sendo simulado verificando SIMULATOR_MODEL_IDENTIFIER
que retornará strings como o iPhone10,3
.
Para executar verificações estáticas:
Xcode 9.2 e versões anteriores: defina seu próprio sinalizador de compilação do Swift (como mostrado em outras respostas).
O Xcode 9.3+ usa a nova condição targetEnvironment:
#if targetEnvironment(simulator)
// for sim only
#else
// for device
#endif
Espero que esta extensão seja útil
extension UIDevice {
static var isSimulator: Bool = {
var isSimulator = false
#if targetEnvironment(simulator)
isSimulator = true
#endif
return isSimulator
}()
}
Uso:
if UIDevice.isSimulator {
print("running on simulator")
}
No Xcode 7.2 (e anterior, mas eu não testei quanto antes), você pode definir um sinalizador de compilação específico da plataforma "-D TARGET_IPHONE_SIMULATOR" para "Qualquer Simulador do iOS".
Examine as configurações de criação do projeto em "Swift Compiler - Customer Flags" e defina o sinalizador em "Other Swift Flags". Você pode definir um sinalizador específico de plataforma clicando no ícone "mais" ao passar o mouse sobre uma configuração de compilação.
Existem algumas vantagens de se fazer desta forma: 1) Você pode usar o mesmo teste condicional ("#if TARGET_IPHONE_SIMULATOR") no seu código Swift e Objective-C. 2) Você pode compilar variáveis que só se aplicam a cada compilação.
Nos sistemas modernos:
#if targetEnvironment(simulator)
// sim
#else
// device
#endif
É fácil.
Runtime, mas mais simples que a maioria das outras soluções aqui:
if TARGET_OS_SIMULATOR != 0 {
// target is current running in the simulator
}
Alternativamente, você pode simplesmente chamar uma função auxiliar Objective-C que retorna um booleano que usa a macro de pré-processador (especialmente se você já estiver mixando em seu projeto).
Edit: Não é a melhor solução, especialmente a partir do Xcode 9.3. Ver resposta de HotJard
Todos descritos aqui Darwin.TargetConditionals : https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Base.subproj/SwiftRuntime/TargetConditionals.h
TARGET_OS_SIMULATOR - Generated code will run under a simulator
TARGET_IPHONE_SIMULATOR
está obsoleto no iOS 9. TARGET_OS_SIMULATOR
é a substituição. Também TARGET_OS_EMBEDDED
está disponível.
De TargetConditionals.h :
#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) ) . . . #define TARGET_OS_SIMULATOR 0 #define TARGET_OS_EMBEDDED 1 #define TARGET_IPHONE_SIMULATOR TARGET_OS_SIMULATOR /* deprecated */ #define TARGET_OS_NANO TARGET_OS_WATCH /* deprecated */
ATUALIZADO PARA O SWIFT 4.1. Use #if targetEnvironment(simulator)
vez disso. SE-0190
Para detectar o simulador no Swift, você pode usar a configuração de compilação:
- Defina esta configuração -D IOS_SIMULATOR no compilador Swift - Custom Flags> Other Swift Flags
- Selecione qualquer SDK do simulador do iOS neste menu suspenso
Agora você pode usar esta declaração para detectar o simulador:
#if IOS_SIMULATOR
print("It's an iOS Simulator")
#else
print("It's a device")
#endif
Além disso, você pode estender a classe UIDevice:
extension UIDevice {
var isSimulator: Bool {
#if IOS_SIMULATOR
return true
#else
return false
#endif
}
}
// Example of usage: UIDevice.current.isSimulator
Informações atualizadas a partir de 20 de fevereiro de 2018
Parece que @russbishop tem uma resposta autoritária que torna esta resposta "incorreta" - mesmo que pareça funcionar por um longo tempo.
Detectar se o aplicativo está sendo construído para dispositivo ou simulador no Swift
Resposta anterior
Com base na resposta do @WZW e nos comentários do @ Pang, criei um utilitário simples struct. Esta solução evita o aviso produzido pela resposta da @WZW.
import Foundation
struct Platform {
static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0
}
}
Exemplo de uso:
if Platform.isSimulator {
print("Running on Simulator")
}