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:

  1. 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.
  2. 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.

Captura de tela das configurações de criação do Xcode


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



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")
}






swift