Dans Objective-C, nous pouvons savoir si une application est en cours de création pour un appareil ou un simulateur à l'aide de macros:
#if TARGET_IPHONE_SIMULATOR
// Simulator
#else
// Device
#endif
Ce sont des macros de compilation et non disponibles au moment de l'exécution.
Comment puis-je réaliser la même chose dans Swift?
Réponses:
Mise à jour 30/01/19
Bien que cette réponse puisse fonctionner, la solution recommandée pour une vérification statique (telle que clarifiée par plusieurs ingénieurs Apple) consiste à définir un indicateur de compilateur personnalisé ciblant les simulateurs iOS. Pour des instructions détaillées sur la façon de procéder, voir la réponse de @ mbelsky .
Réponse originale
Si vous avez besoin d'une vérification statique (par exemple pas un runtime si / sinon), vous ne pouvez pas détecter directement le simulateur, mais vous pouvez détecter iOS sur une architecture de bureau comme suit
Après la version Swift 4.1
Pour plus de précisions, vous pouvez consulter la proposition Swift SE-0190
De toute évidence, cela est faux sur un appareil, mais cela renvoie vrai pour le simulateur iOS, comme spécifié dans la documentation :
Si vous développez pour un simulateur autre que iOS, vous pouvez simplement faire varier le
os
paramètre: par exempleDétectez le simulateur watchOS
Détecter le simulateur tvOS
Ou même détecter n'importe quel simulateur
Si vous êtes plutôt d'accord avec une vérification de l'exécution, vous pouvez inspecter la
TARGET_OS_SIMULATOR
variable (ouTARGET_IPHONE_SIMULATOR
dans iOS 8 et ci-dessous), ce qui est vrai sur un simulateur.Veuillez noter que cela est différent et légèrement plus limité que l'utilisation d'un indicateur de préprocesseur. Par exemple, vous ne pourrez pas l'utiliser à un endroit où a
if/else
est syntaxiquement invalide (par exemple en dehors des étendues de fonctions).Supposons, par exemple, que vous souhaitiez avoir des importations différentes sur l'appareil et sur le simulateur. C'est impossible avec une vérification dynamique, alors que c'est trivial avec une vérification statique.
De plus, comme l'indicateur est remplacé par a
0
ou a1
par le préprocesseur rapide, si vous l'utilisez directement dans uneif/else
expression, le compilateur émet un avertissement concernant le code inaccessible.Pour contourner cet avertissement, consultez l'une des autres réponses.
la source
arch(i386) && os(iOS)
.#if targetEnvironment(simulator)
:) ( github.com/apple/swift-evolution/blob/master/proposals/… )MIS À JOUR POUR SWIFT 4.1. Utilisez
#if targetEnvironment(simulator)
plutôt. La sourcePour détecter le simulateur dans Swift, vous pouvez utiliser la configuration de build:
Vous pouvez maintenant utiliser cette instruction pour détecter le simulateur:
Vous pouvez également étendre la classe UIDevice:
la source
xcconfig
fichiers en utilisantOTHER_SWIFT_FLAGS = TARGET_OS_EMBEDDED
etOTHER_SWIFT_FLAGS[sdk=embeddedsimulator*] = TARGET_OS_SIMULATOR
pour remplacer le simulateur.Informations mises à jour au 20 février 2018
Il semble que @russbishop ait une réponse faisant autorité qui rend cette réponse "incorrecte" - même si cela a semblé fonctionner pendant longtemps.
Détecter si l'application est en cours de création pour un appareil ou un simulateur dans Swift
Réponse précédente
Sur la base de la réponse de @ WZW et des commentaires de @ Pang, j'ai créé une structure utilitaire simple. Cette solution évite les avertissements produits par la réponse de @ WZW.
Exemple d'utilisation:
la source
public let IS_SIMULATOR = (TARGET_OS_SIMULATOR != 0)
... même chose, simplifié. +1 remerciementsTARGET_OS_SIMULATOR != 0
est déjà dans la réponse . C'est la solution donnée par Daniel. Il n'est pas nécessaire de l'ajouter à nouveau dans une variable libre, il est déjà là. Si vous pensez que l'avoir dans une structure est mauvais et que l'avoir dans une variable libre est préférable, postez un commentaire à ce sujet ou faites votre propre réponse. Merci.Depuis Xcode 9.3
iOS 9+:
Swift 3:
Avant iOS 9:
Objectif c:
la source
will never be executed
avertissementSwift 4
Vous pouvez maintenant utiliser
targetEnvironment(simulator)
comme argument.Mis à jour pour Xcode 9.3
la source
Permettez-moi de clarifier certaines choses ici:
TARGET_OS_SIMULATOR
n'est pas défini dans le code Swift dans de nombreux cas; vous pouvez l'obtenir accidentellement en raison d'un en-tête de pontage, mais il est fragile et non pris en charge. Ce n'est même pas possible dans les frameworks. C'est pourquoi certaines personnes ne savent pas si cela fonctionne dans Swift.Pour effectuer des vérifications dynamiques:
La vérification
ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
est parfaitement bien.Vous pouvez également obtenir la simulation du modèle sous-jacent en vérifiant
SIMULATOR_MODEL_IDENTIFIER
qui renverra des chaînes commeiPhone10,3
.Pour effectuer des vérifications statiques:
Xcode 9.2 et versions antérieures: définissez votre propre drapeau de compilation Swift (comme indiqué dans les autres réponses).
Xcode 9.3+ utilise la nouvelle condition targetEnvironment:
la source
targetEnvironment
atterri dans Xcode 9.3. Vous avez besoin d'une version plus récente de Xcode.Ce qui fonctionne pour moi depuis Swift 1.0 est de rechercher une architecture autre que arm:
la source
Runtime, mais plus simple que la plupart des autres solutions ici:
Alternativement, vous pouvez simplement appeler une fonction d'assistance Objective-C qui renvoie un booléen qui utilise la macro du préprocesseur (surtout si vous mixez déjà dans votre projet).
Edit: Pas la meilleure solution, surtout depuis Xcode 9.3. Voir la réponse de HotJard
la source
== 0
place de!= 0
. L'utiliser comme écrit ci-dessus, même avec unelse
bloc après, ne produit aucun avertissement dans Swift 4 Xcode Version 9.2 (9C40b)Dans les systèmes modernes:
C'est très simple.
la source
TARGET_IPHONE_SIMULATOR
est obsolète dans iOS 9.TARGET_OS_SIMULATOR
est le remplacement. Est égalementTARGET_OS_EMBEDDED
disponible.De TargetConditionals.h :
la source
J'espère que cette extension sera utile.
Usage:
la source
Dans Xcode 7.2 (et plus tôt mais je n'ai pas testé combien auparavant), vous pouvez définir un indicateur de build spécifique à la plate-forme "-D TARGET_IPHONE_SIMULATOR" pour "Any iOS Simulator".
Regardez dans les paramètres de construction du projet sous "Compilateur Swift - Indicateurs client", puis définissez l'indicateur dans "Autres indicateurs Swift". Vous pouvez définir un indicateur spécifique à la plate-forme en cliquant sur l'icône «plus» lorsque vous survolez une configuration de build.
Il y a quelques avantages à le faire de cette façon: 1) Vous pouvez utiliser le même test conditionnel ("#if TARGET_IPHONE_SIMULATOR") dans votre code Swift et Objective-C. 2) Vous pouvez compiler des variables qui ne s'appliquent qu'à chaque build.
Capture d'écran des paramètres de construction de Xcode
la source
Tous décrits ici Darwin.TargetConditionals : https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Base.subproj/SwiftRuntime/TargetConditionals.h
TARGET_OS_SIMULATOR - Generated code will run under a simulator
la source
J'ai utilisé ce code ci-dessous dans Swift 3
la source
Swift 4:
Actuellement, je préfère utiliser la classe ProcessInfo pour savoir si le périphérique est un simulateur et quel type de périphérique est utilisé:
Mais, comme vous le savez, ce
simModelCode
n'est pas un code confortable pour comprendre immédiatement quel type de simulateur a été lancé, donc, si vous en avez besoin, vous pouvez essayer de voir cette autre réponse SO pour déterminer le modèle actuel d'iPhone / appareil et d'avoir un humain plus chaîne lisible.la source
Voici un exemple Xcode 11 Swift basé sur la réponse impressionnante de HotJard ci - dessus , cela ajoute également un
isDevice
Bool et utilise à laSIMULATOR_UDID
place du nom. Des affectations variables sont effectuées sur chaque ligne afin que vous puissiez les examiner plus facilement dans le débogueur si vous le souhaitez.Il y a aussi l'entrée du dictionnaire
DTPlatformName
qui devrait contenirsimulator
.la source
Utilisez ce code ci-dessous:
Fonctionne pour
Swift 4
etXcode 9.4.1
la source
Xcode 11, Swift 5
la source
En plus d'autres réponses.
Dans Objective-c, assurez-vous simplement que vous avez inclus TargetConditionals .
#include <TargetConditionals.h>
avant d'utiliser
TARGET_OS_SIMULATOR
.la source