Comment puis-je déterminer par programme si mon application est exécutée dans le simulateur iphone?

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

Question

Comme l'indique la question, j'aimerais principalement savoir si mon code est exécuté dans le simulateur, mais j'aimerais également connaître la version spécifique de l'iPhone en cours d'exécution ou en cours de simulation.

EDIT: J'ai ajouté le mot "par programme" au nom de la question. Le but de ma question est de pouvoir inclure et exclure du code de manière dynamique en fonction de la version / du simulateur en cours d'exécution. Je chercherais donc vraiment une directive du préprocesseur capable de me fournir ces informations.

Était-ce utile?

La solution

Déjà demandé, mais avec un titre très différent.

Quelles # définitions sont définies par Xcode lorsque compilation pour iPhone

Je répète ma réponse à partir de là:

Il se trouve dans la documentation du SDK sous "Compiler le code source de manière conditionnelle"

.

La définition pertinente est TARGET_OS_SIMULATOR, définie dans /usr/include/TargetConditionals.h dans la structure iOS. Sur les versions précédentes de la chaîne d’outils, vous deviez écrire:

#include "TargetConditionals.h"

mais cela n'est plus nécessaire dans la chaîne d'outils actuelle (Xcode 6 / iOS8).

Ainsi, par exemple, si vous souhaitez vérifier que vous exécutez sur un périphérique, vous devez effectuer

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

en fonction de ce qui convient à votre cas d'utilisation.

Autres conseils

Code mis à jour:

Ceci est censé fonctionner officiellement.

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

Message d'origine (déconseillé depuis) ??

Ce code vous dira si vous utilisez un simulateur.

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

Pas de directive pré-processeur, mais c’était ce que je cherchais quand je suis arrivé à cette question;

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

La meilleure façon de le faire est:

#if TARGET_IPHONE_SIMULATOR

et non

#ifdef TARGET_IPHONE_SIMULATOR

puisqu'il est toujours défini: 0 ou 1

IL Y A UN MEILLEUR MOYEN MAINTENANT!

À partir de Xcode 9.3 beta 4, vous pouvez utiliser #if targetEnvironment (simulateur) pour vérifier.

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

MISE À JOUR
Xcode 10 et iOS 12 SDK prennent également en charge cette fonctionnalité.

Dans le cas de Swift, nous pouvons implémenter ce qui suit

Nous pouvons créer une structure qui vous permet de créer des données structurées

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

Ensuite, si nous voulions détecter si une application est en cours de construction pour un appareil ou un simulateur dans Swift, alors.

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

Toutes ces réponses sont bonnes, mais cela confond un débutant comme moi, car cela ne clarifie pas les vérifications de compilation et d’exécution. Les préprocesseurs sont avant la compilation, mais nous devrions le préciser

Cet article de blog présente Comment détecter le simulateur iPhone? clairement

Exécution

Tout d’abord, discutons brièvement. UIDevice vous fournit déjà des informations sur le périphérique

[[UIDevice currentDevice] model]

vous renverra & # 8220; iPhone Simulator & # 8221; ou & # 8220; iPhone & # 8221; en fonction de l'emplacement de l'application.

Temps de compilation

Cependant, ce que vous voulez, c'est utiliser le temps de compilation défini. Pourquoi? Parce que vous compilez votre application uniquement pour qu'elle soit exécutée à l'intérieur du simulateur ou sur le périphérique. Apple crée une définition appelée TARGET_IPHONE_SIMULATOR . Alors regardons le code:

#if TARGET_IPHONE_SIMULATOR

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

#endif

Fonctionne pour Swift 4 et Xcode 9.4.1

Utilisez ce code:

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

Les réponses précédentes sont un peu datées. J'ai constaté qu'il suffisait d'interroger la macro TARGET_IPHONE_SIMULATOR ( inutile d'inclure d'autres fichiers d'en-tête [en supposant que vous codiez pour iOS]).

J'ai essayé TARGET_OS_IPHONE , mais la même valeur (1) a été utilisée lors de l'exécution sur un appareil et un simulateur réels. C'est pourquoi je vous recommande d'utiliser TARGET_IPHONE_SIMULATOR à la place.

J'ai eu le même problème, à la fois TARGET_IPHONE_SIMULATOR et TARGET_OS_IPHONE sont toujours définis et sont définis sur 1. La solution de Pete fonctionne, bien sûr, mais si cela vous arrive Construisez sur quelque chose d'autre qu'Intel (peu probable, mais qui sait), voici quelque chose de sûr tant que le matériel de l'iPhone ne change pas (votre code fonctionnera toujours pour les iphones actuellement 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

Mettez cela à un endroit pratique, puis supposez que les constantes TARGET _ * ont été définies correctement.

Pour Swift 4.2 / xCode 10

J'ai créé une extension sur UIDevice afin de pouvoir facilement demander si le simulateur est en cours d'exécution.

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

Dans mon AppDelegate , par exemple, j'utilise cette méthode pour décider si l'enregistrement pour la notification à distance est nécessaire, ce qui n'est pas possible pour le simulateur.

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

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

Quelqu'un a-t-il déjà envisagé de répondre ici ?

Je suppose que l'équivalent objectif-c serait

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

Pour inclure tous les types de "simulateurs"

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

Avec Swift 4.2 (Xcode 10), nous pouvons le faire

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

Ma réponse est basée sur la réponse de @Daniel Magnusson et les commentaires de @Nuthatch et de @ n.Drake. et je l’écris pour gagner du temps pour les utilisateurs rapides travaillant sur iOS9 et les versions ultérieures.

Voici ce qui a fonctionné pour moi:

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

/// Renvoie true si son simulateur et non un périphérique

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

Apple a ajouté un support pour vérifier que l'application est ciblée pour le simulateur avec les éléments suivants:

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

si rien ne fonctionne, essayez ceci

public struct Platform {

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

}

Cela a fonctionné le mieux pour moi

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


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

}

À mon avis, la réponse (présentée ci-dessus et répétée ci-dessous):

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

est la meilleure réponse car il est évidemment exécuté à RUNTIME par opposition à une DIRECTIVE COMPILE.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top