ios - emulator - Como posso determinar programaticamente se meu aplicativo está sendo executado no simulador do iPhone?




simulator iphone windows (15)

Código atualizado:

Isto supostamente funciona oficialmente.

#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif

Post original (desde obsoleto)

Este código dirá se você está executando em um simulador.

#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif

Como a pergunta afirma, eu gostaria principalmente de saber se meu código está sendo executado no simulador, mas também estaria interessado em conhecer a versão específica do iPhone que está sendo executada ou simulada.

EDIT: eu adicionei a palavra 'programaticamente' para o nome da pergunta. O ponto da minha pergunta é ser capaz de incluir / excluir código dinamicamente dependendo de qual versão / simulador está sendo executado, então eu realmente estaria procurando algo como uma diretiva de pré-processador que possa me fornecer esta informação.


/// Retorna true se seu simulador e não um dispositivo

public static var isSimulator: Bool {
    #if (arch(i386) || arch(x86_64)) && os(iOS)
        return true
    #else
        return false
    #endif
}

A melhor maneira de fazer isso é:

#if TARGET_IPHONE_SIMULATOR

e não

#ifdef TARGET_IPHONE_SIMULATOR

desde sempre definido: 0 ou 1


Alguém já considerou a resposta fornecida here ?

Eu suponho que o equivalente objetivo-c seria

+ (BOOL)isSimulator {
    NSOperatingSystemVersion ios9 = {9, 0, 0};
    NSProcessInfo *processInfo = [NSProcessInfo processInfo];
    if ([processInfo isOperatingSystemAtLeastVersion:ios9]) {
        NSDictionary<NSString *, NSString *> *environment = [processInfo environment];
        NSString *simulator = [environment objectForKey:@"SIMULATOR_DEVICE_NAME"];
        return simulator != nil;
    } else {
        UIDevice *currentDevice = [UIDevice currentDevice];
        return ([currentDevice.model rangeOfString:@"Simulator"].location != NSNotFound);
    }
}

Com o Swift 4.2 (Xcode 10), podemos fazer isso

#if targetEnvironment(simulator)
  //simulator code
#else 
  #warning("Not compiling for simulator")
#endif


Funciona para o Swift 4 e o Xcode 9.4.1

Use este código:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif

HÁ UMA MELHOR MANEIRA AGORA!

A partir do Xcode 9.3 beta 4, você pode usar o #if targetEnvironment(simulator) para verificar.

#if targetEnvironment(simulator)
//Your simulator code
#endif

ATUALIZAR
O Xcode 10 e o iOS 12 SDK também suportam isso.


Já perguntei, mas com um título bem diferente.

O que #defines são configurados pelo Xcode ao compilar para o iPhone

Vou repetir a minha resposta a partir daí:

Está nos documentos do SDK em "Compilar código-fonte condicionalmente"

A definição relevante é TARGET_OS_SIMULATOR, que é definida em /usr/include/TargetConditionals.h na estrutura do iOS. Nas versões anteriores do toolchain, você tinha que escrever:

#include "TargetConditionals.h"

mas isso não é mais necessário no conjunto de ferramentas atual (Xcode 6 / iOS8).

Então, por exemplo, se você quiser verificar se você está rodando no dispositivo, você deve fazer

#if TARGET_OS_SIMULATOR
    // Simulator-specific code
#else
    // Device-specific code
#endif

dependendo do que é apropriado para o seu caso de uso.


Minha resposta é baseada na resposta do @Daniel Magnusson e comentários do @Nuthatch e @ n.Drake. e eu escrevo para poupar algum tempo para usuários rápidos trabalhando no iOS9 e em diante.

Isto é o que funcionou para mim:

if UIDevice.currentDevice().name.hasSuffix("Simulator"){
    //Code executing on Simulator
} else{
    //Code executing on Device
}

Na minha opinião, a resposta (apresentada acima e repetida abaixo):

NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
    //device is simulator
}

é a melhor resposta porque é obviamente executada no RUNTIME versus ser um COMPIL DIRECTIVE.


Para incluir todos os tipos de "simuladores"

NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    // we are running in a simulator
}

No caso do Swift, podemos implementar o seguinte

Podemos criar struct que permite criar um dado estruturado

struct Platform {
    static let isSimulator: Bool = {
        #if arch(i386) || arch(x86_64)
            return true
        #endif
        return false
    }()
}

Então, se quiséssemos detectar se o aplicativo está sendo construído para o dispositivo ou simulador no Swift então.

if Platform.isSimulator {
    // Do one thing
}
else {
    // Do the other
}

Para Swift 4.2 / xCode 10

Eu criei uma extensão no UIDevice, então eu posso facilmente perguntar se o simulador está rodando.

// UIDevice+CheckSimulator.swift

import UIKit

extension UIDevice {

    /// Checks if the current device that runs the app is xCode's simulator
    static func isSimulator() -> Bool {        
        #if targetEnvironment(simulator)
            return true
        #else
            return false
        #endif
    }
}

No meu AppDelegate, por exemplo, eu uso esse método para decidir se o registro para notificação remota é necessário, o que não é possível para o simulador.

// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {

    // REGISTER FOR SILENT REMOTE NOTIFICATION
    application.registerForRemoteNotifications()
}

se nada funcionasse, tente isso

public struct Platform {

    public static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
    }

}






ios-simulator