web-dev-qa-db-fra.com

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

Comme le dit la question, j'aimerais principalement savoir si mon code est en cours d'exécution 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 cette information.

254
Jeffrey Meyer

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

Quelles sont les définitions définies par Xcode lors de la compilation pour iPhone

Je vais répéter ma réponse à partir de là:

C'est dans la documentation du SDK sous "Compiler le code source de façon 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 ce n'est plus nécessaire dans la chaîne d'outils actuelle (Xcode 6/iOS8).

Ainsi, par exemple, si vous voulez vérifier que vous utilisez le périphérique, vous devriez faire

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

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

348
Airsource Ltd

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

Poste d'origine (depuis obsolète)

Ce code vous dira si vous utilisez un simulateur.

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

Pas de directive du pré-processeur, mais c’était ce que je recherchais lorsque j’en suis venu à cette question;

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

La meilleure façon de faire est:

#if TARGET_IPHONE_SIMULATOR

et pas

#ifdef TARGET_IPHONE_SIMULATOR

depuis toujours défini: 0 ou 1

54
Taranfx

En cas de Swift, nous pouvons mettre en œuvre ce qui suit

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

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
}
30
Nischal Hada

IL IS UNE MEILLEURE FAÇON MAINTENANT! 

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

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

METTRE À JOUR
Xcode 10 et iOS 12 SDK le supporte également.

23
Stefan Vasiljevic

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 montre Comment détecter le simulateur iPhone? clairement 

Runtime

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

[[UIDevice currentDevice] model]

vous retournera «iPhone Simulator» ou «iPhone» 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
8
onmyway133
6
CedricSoubrie

Les réponses précédentes sont un peu datées. J'ai constaté que tout ce que vous avez à faire est d'interroger la macro TARGET_IPHONE_SIMULATOR ( inutile d'inclure d'autres fichiers d'en-tête [en supposant que vous codez pour iOS]).

J'ai essayé TARGET_OS_IPHONE mais il a retourné la même valeur (1) lors de l'exécution sur un appareil et un simulateur réels, c'est pourquoi je recommande d'utiliser plutôt TARGET_IPHONE_SIMULATOR.

6
Stunner

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 à 1. La solution de Pete fonctionne, bien sûr, mais si vous vous basez sur autre chose qu'Intel (improbable, mais qui sait), voici quelque chose qui est sûr tant que le matériel iphone ne change pas (votre code fonctionnera donc 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.

4
Martin

Fonctionne pour Swift 4 et Xcode 9.4.1

Utilisez ce code:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif
3
Haroldo Gondim

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()
}
2
LukeSideWalker

Quelqu'un a-t-il 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);
    }
}
2
Vijay Sharma

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
}
1
jeffr

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

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

/// 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
}
0
Pratyush Pratik

si rien n'a fonctionné, essayez ceci

public struct Platform {

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

}
0
Aklesh Rathaur

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
0
David Corbin

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 de Swift travaillant sur iOS9 et les versions ultérieures.

C'est ce qui a fonctionné pour moi:

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

Solution Swift 4

static let isSimulator: Bool = {
    return TARGET_OS_SIMULATOR == 1
}()

TARGET_OS_SIMULATOR est situé dans le fichier Darwin.TargetConditionals.Swift.

0
kamwysoc