¿Cómo puedo determinar mediante programación si mi aplicación se está ejecutando en el simulador de iPhone?

StackOverflow https://stackoverflow.com/questions/458304

Pregunta

Como dice la pregunta, principalmente me gustaría saber si mi código se está ejecutando o no en el simulador, pero también estaría interesado en conocer la versión específica de iPhone que se está ejecutando o simulando.

EDITAR: agregué la palabra 'programáticamente' al nombre de la pregunta. El punto de mi pregunta es poder incluir / excluir dinámicamente el código dependiendo de la versión / simulador que se esté ejecutando, por lo que realmente estaría buscando algo como una directiva de preprocesador que pueda proporcionarme esta información.

¿Fue útil?

Solución

Ya preguntado, pero con un título muy diferente.

¿Qué #defines configura Xcode cuando compilando para iPhone

Repetiré mi respuesta desde allí:

Está en los documentos del SDK en " Compilación de código fuente condicionalmente "

La definición relevante es TARGET_OS_SIMULATOR, que se define en /usr/include/TargetConditionals.h dentro del marco de iOS. En versiones anteriores de la cadena de herramientas, tenía que escribir:

#include "TargetConditionals.h"

pero esto ya no es necesario en la cadena de herramientas actual (Xcode 6 / iOS8).

Entonces, por ejemplo, si desea verificar que se está ejecutando en el dispositivo, debe hacerlo

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

dependiendo de cuál sea apropiado para su caso de uso.

Otros consejos

Código actualizado:

Se supone que 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

Publicación original (desde obsoleto)

Este código le dirá si está ejecutando en un simulador.

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

No directiva de preprocesador, pero esto era lo que estaba buscando cuando llegué a esta pregunta;

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

La mejor manera de hacer esto es:

#if TARGET_IPHONE_SIMULATOR

y no

#ifdef TARGET_IPHONE_SIMULATOR

ya que siempre está definido: 0 o 1

¡HAY UNA MEJOR MANERA AHORA!

A partir de Xcode 9.3 beta 4, puede usar #if targetEnvironment (simulator) para verificar.

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

ACTUALIZACIÓN
Xcode 10 y iOS 12 SDK también lo admiten.

En el caso de Swift podemos implementar los siguientes

Podemos crear una estructura que le permite crear datos estructurados

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

Entonces, si quisiéramos detectar si la aplicación se está creando para un dispositivo o simulador en Swift, entonces.

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

Todas esas respuestas son buenas, pero de alguna manera confunde a los novatos como yo, ya que no aclara la verificación de compilación y la verificación de tiempo de ejecución. El preprocesador es anterior al tiempo de compilación, pero debemos aclararlo

Este artículo de blog muestra Cómo detectar el simulador de iPhone? claramente

Tiempo de ejecución

En primer lugar, discutamos brevemente. UIDevice ya le proporciona información sobre el dispositivo

[[UIDevice currentDevice] model]

le devolverá & # 8220; iPhone Simulator & # 8221; o & # 8220; iPhone & # 8221; según dónde se ejecute la aplicación.

Tiempo de compilación

Sin embargo, lo que quiere es usar el tiempo de compilación definido. ¿Por qué? Porque compila su aplicación estrictamente para que se ejecute dentro del Simulador o en el dispositivo. Apple hace una definición llamada TARGET_IPHONE_SIMULATOR . Así que veamos el código:

#if TARGET_IPHONE_SIMULATOR

NSLog(@"Running in Simulator - no app store or giro");

#endif

Funciona para Swift 4 y Xcode 9.4.1

Use este código:

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

Las respuestas anteriores están un poco anticuadas. Descubrí que todo lo que necesita hacer es consultar la macro TARGET_IPHONE_SIMULATOR ( no es necesario incluir ningún otro archivo de encabezado [suponiendo que esté codificando para iOS]).

Intenté TARGET_OS_IPHONE pero me devolvió el mismo valor (1) cuando se ejecutaba en un dispositivo y simulador real, por eso recomiendo usar TARGET_IPHONE_SIMULATOR .

En rápido:

#if (arch(i386) || arch(x86_64))
...            
#endif

De Detectar si la aplicación es siendo construido para dispositivo o simulador en Swift

Tuve el mismo problema, tanto TARGET_IPHONE_SIMULATOR como TARGET_OS_IPHONE siempre están definidos y están configurados en 1. La solución de Pete funciona, por supuesto, pero si alguna vez construir sobre otra cosa que no sea Intel (poco probable, pero quién sabe), aquí hay algo que es seguro siempre que el hardware del iPhone no cambie (por lo que su código siempre funcionará para los iphones actualmente disponibles):

#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif

Ponga eso en un lugar conveniente, y luego pretenda que las constantes TARGET_ * se definieron correctamente.

Para Swift 4.2 / xCode 10

Creé una extensión en UIDevice, por lo que puedo preguntar fácilmente si el simulador se está ejecutando.

// 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
    }
}

En mi AppDelegate , por ejemplo, uso este método para decidir si es necesario registrarse para la notificación remota, lo que no es posible para el simulador.

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

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

¿Alguien ha considerado la respuesta proporcionada aquí ?

Supongo que el objetivo-c equivalente sería

+ (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);
    }
}

Para incluir todos los tipos de "simuladores"

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

Con Swift 4.2 (Xcode 10), podemos hacer esto

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

Mi respuesta se basa en la respuesta de @Daniel Magnusson y los comentarios de @Nuthatch y @ n.Drake. y lo escribo para ahorrar tiempo a los usuarios rápidos que trabajan en iOS9 y en adelante.

Esto es lo que funcionó para mí:

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

/// Devuelve verdadero si es un simulador y no un dispositivo

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

Apple ha agregado soporte para verificar que la aplicación esté dirigida al simulador con lo siguiente:

#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif

si nada funcionó, intente esto

public struct Platform {

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

}

Esto funcionó mejor para mí

NSString *name = [[UIDevice currentDevice] name];


if ([name isEqualToString:@"iPhone Simulator"]) {

}

En mi opinión, la respuesta (presentada arriba y repetida abajo):

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

es la mejor respuesta porque obviamente se ejecuta en tiempo de ejecución en lugar de ser una DIRECTIVA DE COMPILACIÓN.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top