In Objective-C können wir mithilfe von Makros feststellen, ob eine App für ein Gerät oder einen Simulator erstellt wird:
#if TARGET_IPHONE_SIMULATOR
// Simulator
#else
// Device
#endif
Dies sind Kompilierungszeitmakros, die zur Laufzeit nicht verfügbar sind.
Wie kann ich dasselbe in Swift erreichen?
Antworten:
Update 30/01/19
Während diese Antwort möglicherweise funktioniert, besteht die empfohlene Lösung für eine statische Überprüfung (wie von mehreren Apple-Ingenieuren geklärt) darin, ein benutzerdefiniertes Compiler-Flag für iOS-Simulatoren zu definieren. Ausführliche Anweisungen dazu finden Sie in der Antwort von @ mbelsky .
Ursprüngliche Antwort
Wenn Sie eine statische Überprüfung benötigen (z. B. keine Laufzeit, wenn / sonst), können Sie den Simulator nicht direkt erkennen, aber Sie können iOS auf einer Desktop-Architektur wie folgt erkennen
Nach Swift 4.1 Version
Weitere Informationen finden Sie im Swift- Vorschlag SE-0190
Dies ist auf einem Gerät eindeutig falsch, gibt jedoch für den iOS-Simulator den Wert true zurück, wie in der Dokumentation angegeben :
Wenn Sie für einen anderen Simulator als iOS entwickeln, können Sie einfach den
os
Parameter variieren : zErkennen Sie den watchOS- Simulator
Erkennen Sie den tvOS- Simulator
Oder erkennen Sie sogar einen Simulator
Wenn Sie stattdessen mit einer Laufzeitprüfung einverstanden sind, können Sie die
TARGET_OS_SIMULATOR
Variable (oderTARGET_IPHONE_SIMULATOR
in iOS 8 und niedriger) überprüfen, was auf einem Simulator der Fall ist.Bitte beachten Sie, dass dies anders und etwas eingeschränkter ist als die Verwendung eines Präprozessor-Flags. Zum Beispiel können Sie es nicht an Orten verwenden, an denen a
if/else
syntaktisch ungültig ist (z. B. außerhalb von Funktionsbereichen).Angenommen, Sie möchten unterschiedliche Importe auf dem Gerät und im Simulator durchführen. Dies ist bei einer dynamischen Prüfung unmöglich, während es bei einer statischen Prüfung trivial ist.
Da das Flag durch den schnellen Präprozessor durch ein
0
oder ein ersetzt1
wird, gibtif/else
der Compiler eine Warnung vor nicht erreichbarem Code aus , wenn Sie es direkt in einem Ausdruck verwenden.Um diese Warnung zu umgehen, lesen Sie eine der anderen Antworten.
quelle
arch(i386) && os(iOS)
.#if targetEnvironment(simulator)
:) ( github.com/apple/swift-evolution/blob/master/proposals/… )FÜR SWIFT veraltet 4.1. Verwenden Sie
#if targetEnvironment(simulator)
stattdessen. QuelleUm den Simulator in Swift zu erkennen, können Sie die Build-Konfiguration verwenden:
Jetzt können Sie diese Anweisung verwenden, um den Simulator zu erkennen:
Sie können auch die UIDevice-Klasse erweitern:
quelle
xcconfig
Dateien einrichten, indem SieOTHER_SWIFT_FLAGS = TARGET_OS_EMBEDDED
undOTHER_SWIFT_FLAGS[sdk=embeddedsimulator*] = TARGET_OS_SIMULATOR
für den Simulator überschreiben.Die Informationen wurden am 20. Februar 2018 aktualisiert
Es sieht so aus, als hätte @russbishop eine maßgebliche Antwort, die diese Antwort "falsch" macht - obwohl sie lange Zeit zu funktionieren schien.
Ermitteln Sie, ob in Swift eine App für ein Gerät oder einen Simulator erstellt wird
Vorherige Antwort
Basierend auf der Antwort von @ WZW und den Kommentaren von @ Pang habe ich eine einfache Dienstprogrammstruktur erstellt. Diese Lösung vermeidet Warnungen, die durch die Antwort von @ WZW erzeugt werden.
Anwendungsbeispiel:
quelle
public let IS_SIMULATOR = (TARGET_OS_SIMULATOR != 0)
... dasselbe, vereinfacht. +1 dankeTARGET_OS_SIMULATOR != 0
ist schon in der Antwort . Es ist die Lösung von Daniel. Es ist nicht erforderlich, es erneut in eine kostenlose Variable einzufügen, es ist bereits vorhanden. Wenn Sie der Meinung sind, dass es schlecht ist, es in einer Struktur zu haben und es in einer freien Variablen zu haben, ist es besser, einen Kommentar dazu zu schreiben oder Ihre eigene Antwort zu geben. Vielen Dank.Ab Xcode 9.3
iOS 9+:
Swift 3:
Vor iOS 9:
Ziel c:
quelle
will never be executed
WarnungSwift 4
Sie können jetzt
targetEnvironment(simulator)
als Argument verwenden.Aktualisiert für Xcode 9.3
quelle
Lassen Sie mich hier einige Dinge klarstellen:
TARGET_OS_SIMULATOR
wird in vielen Fällen nicht im Swift-Code festgelegt; Möglicherweise wird es aufgrund eines Bridging-Headers versehentlich importiert, dies ist jedoch spröde und wird nicht unterstützt. Es ist auch nicht einmal in Frameworks möglich. Aus diesem Grund sind einige Leute verwirrt darüber, ob dies in Swift funktioniert.So führen Sie dynamische Überprüfungen durch:
Die Überprüfung
ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
ist vollkommen in Ordnung.Sie können das zugrunde liegende Modell auch simulieren lassen, indem Sie überprüfen,
SIMULATOR_MODEL_IDENTIFIER
welche Zeichenfolgen wie zurückgegeben werdeniPhone10,3
.So führen Sie statische Überprüfungen durch:
Xcode 9.2 und früher: Definieren Sie Ihr eigenes Swift-Kompilierungsflag (wie in anderen Antworten gezeigt).
Xcode 9.3+ verwendet die neue targetEnvironment-Bedingung:
quelle
targetEnvironment
landete in Xcode 9.3. Sie benötigen eine neuere Version von Xcode.Was für mich seit Swift 1.0 funktioniert, ist die Suche nach einer anderen Architektur als arm:
quelle
Laufzeit, aber einfacher als die meisten anderen Lösungen hier:
Alternativ können Sie einfach eine Objective-C-Hilfsfunktion aufrufen, die einen Booleschen Wert zurückgibt, der das Präprozessor-Makro verwendet (insbesondere, wenn Sie Ihr Projekt bereits einmischen).
Bearbeiten: Nicht die beste Lösung, insbesondere ab Xcode 9.3. Siehe die Antwort von HotJard
quelle
== 0
anstelle von verwende!= 0
. Die Verwendung wie oben beschrieben, auch mit einemelse
Block danach, erzeugt keine Warnungen in Swift 4 Xcode Version 9.2 (9C40b)In modernen Systemen:
Es ist einfach.
quelle
TARGET_IPHONE_SIMULATOR
ist in iOS 9 veraltet.TARGET_OS_SIMULATOR
ist der Ersatz. EbenfallsTARGET_OS_EMBEDDED
verfügbar.Von TargetConditionals.h :
quelle
Ich hoffe, diese Erweiterung ist praktisch.
Verwendungszweck:
quelle
In Xcode 7.2 (und früher, aber ich habe noch nicht getestet, wie viel früher) können Sie ein plattformspezifisches Build-Flag "-D TARGET_IPHONE_SIMULATOR" für "Any iOS Simulator" setzen.
Schauen Sie in den Projekterstellungseinstellungen unter "Swift Compiler - Kundenflags" nach und setzen Sie dann das Flag unter "Andere Swift Flags". Sie können ein plattformspezifisches Flag setzen, indem Sie auf das Pluszeichen klicken, wenn Sie den Mauszeiger über eine Build-Konfiguration bewegen.
Dies hat einige Vorteile: 1) Sie können denselben bedingten Test ("#if TARGET_IPHONE_SIMULATOR") in Ihrem Swift- und Objective-C-Code verwenden. 2) Sie können Variablen kompilieren, die nur für jeden Build gelten.
Screenshot der Xcode-Build-Einstellungen
quelle
Alle hier beschriebenen 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
quelle
Ich habe diesen Code in Swift 3 verwendet
quelle
Swift 4:
Derzeit bevorzuge ich die ProcessInfo- Klasse, um festzustellen , ob das Gerät ein Simulator ist und welche Art von Gerät verwendet wird:
Wie Sie wissen,
simModelCode
ist es jedoch kein bequemer Code, sofort zu verstehen, welche Art von Simulator gestartet wurde. Wenn Sie dies benötigen, können Sie versuchen, diese andere SO- Antwort anzuzeigen , um das aktuelle iPhone- / Gerätemodell zu ermitteln und einen menschlicheren Charakter zu haben lesbare Zeichenfolge.quelle
Hier ist ein Xcode 11 Swift Beispiel basiert weg HotJard die ehrfürchtige Antwort oben , das macht auch eine
isDevice
Bool und verwendetSIMULATOR_UDID
statt Namen. Variablenzuweisungen werden in jeder Zeile vorgenommen, damit Sie sie im Debugger leichter überprüfen können, wenn Sie dies wünschen.Es gibt auch den Wörterbucheintrag, der
DTPlatformName
enthalten solltesimulator
.quelle
Verwenden Sie den folgenden Code:
Funktioniert für
Swift 4
undXcode 9.4.1
quelle
Xcode 11, Swift 5
quelle
Neben anderen Antworten.
Stellen Sie in Objective-c einfach sicher, dass Sie TargetConditionals eingeschlossen haben .
#include <TargetConditionals.h>
vor dem Gebrauch
TARGET_OS_SIMULATOR
.quelle