Wie die Frage ausführt, möchte ich hauptsächlich wissen, ob mein Code im Simulator ausgeführt wird oder nicht. Ich wäre aber auch daran interessiert, welche iPhone-Version gerade ausgeführt wird oder simuliert wird.
BEARBEITEN: Ich habe das Wort "programmgesteuert" zum Fragennamen hinzugefügt. Meine Frage ist, in der Lage zu sein, Code dynamisch einzuschließen/auszuschließen, je nachdem welche Version/Simulator ausgeführt wird. Ich würde also wirklich nach einer Pre-Prozessor-Direktive suchen, die mir diese Informationen liefert.
Bereits gefragt, aber mit einem ganz anderen Titel.
Welche #Defines werden von Xcode beim Kompilieren für das iPhone eingerichtet
Ich werde meine Antwort von dort wiederholen:
Es befindet sich in den SDK-Dokumenten unter "Bedingter Quellcode kompilieren".
Die relevante Definition ist TARGET_OS_SIMULATOR, die in /usr/include/TargetConditionals.h im iOS-Framework definiert ist. In früheren Versionen der Toolchain mussten Sie schreiben:
#include "TargetConditionals.h"
dies ist jedoch in der aktuellen (Xcode 6/iOS8) Toolchain nicht mehr erforderlich.
Wenn Sie beispielsweise prüfen möchten, ob Sie auf einem Gerät laufen, sollten Sie dies tun
#if TARGET_OS_SIMULATOR
// Simulator-specific code
#else
// Device-specific code
#endif
abhängig davon, welche für Ihren Anwendungsfall geeignet ist.
Dies soll offiziell funktionieren.
#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#Elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif
Dieser Code sagt Ihnen, ob Sie in einem Simulator laufen.
#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif
Keine Vorprozessor-Direktive, aber das war es, wonach ich gesucht hatte, als ich zu dieser Frage kam.
NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}
Der beste Weg dies zu tun ist:
#if TARGET_IPHONE_SIMULATOR
und nicht
#ifdef TARGET_IPHONE_SIMULATOR
da es immer definiert ist: 0 oder 1
Im Falle von Swift können wir Folgendes implementieren
Wir können struct erstellen, mit dem Sie strukturierte Daten erstellen können
struct Platform {
static let isSimulator: Bool = {
#if Arch(i386) || Arch(x86_64)
return true
#endif
return false
}()
}
Dann wollten wir herausfinden, ob in Swift eine App für ein Gerät oder einen Simulator erstellt wird.
if Platform.isSimulator {
// Do one thing
}
else {
// Do the other
}
DORT IS EIN BESSERER WEG JETZT!
Ab Xcode 9.3 Beta 4 können Sie #if targetEnvironment(simulator)
zur Überprüfung verwenden.
#if targetEnvironment(simulator)
//Your simulator code
#endif
UPDATE
Xcode 10 und iOS 12 SDK unterstützen dies ebenfalls.
Alle diese Antworten sind gut, aber es verwirrt irgendwie Neulinge wie mich, da sie Compilierprüfung und Laufzeitprüfung nicht klarstellen. Preprozessor steht vor der Kompilierzeit, aber wir sollten es klarer machen
Dieser Blogartikel zeigt Wie erkennt man den iPhone-Simulator? deutlich
Laufzeit
Lassen Sie uns zunächst kurz besprechen. UIDevice liefert Ihnen bereits Informationen zum Gerät
[[UIDevice currentDevice] model]
sie erhalten einen "iPhone Simulator" oder "iPhone", je nachdem, wo die App ausgeführt wird.
Kompilierzeit
Was Sie jedoch wollen, ist die Verwendung von Kompilierzeiten. Warum? Weil Sie Ihre App unbedingt kompilieren, um entweder im Simulator oder auf dem Gerät ausgeführt zu werden. Apple macht eine Definition namens TARGET_IPHONE_SIMULATOR
. Schauen wir uns den Code an:
#if TARGET_IPHONE_SIMULATOR
NSLog(@"Running in Simulator - no app store or giro");
#endif
In Swift:
#if (Arch(i386) || Arch(x86_64))
...
#endif
Von Ermitteln, ob in Swift eine App für ein Gerät oder einen Simulator erstellt wird
Die vorherigen Antworten sind etwas veraltet. Ich habe festgestellt, dass Sie nur das TARGET_IPHONE_SIMULATOR
-Makro abfragen müssen ( es müssen keine weiteren Header-Dateien eingefügt werden [vorausgesetzt, Sie sind für iOS programmiert]).
Ich habe TARGET_OS_IPHONE
versucht, aber es lieferte den gleichen Wert (1), wenn er auf einem tatsächlichen Gerät und Simulator ausgeführt wurde. Deshalb empfehle ich, stattdessen TARGET_IPHONE_SIMULATOR
zu verwenden.
Ich hatte das gleiche Problem, sowohl TARGET_IPHONE_SIMULATOR
als auch TARGET_OS_IPHONE
sind immer definiert und auf 1 gesetzt. Die Lösung von Pete funktioniert natürlich, aber wenn Sie jemals auf etwas anderem als intel aufbauen (unwahrscheinlich, aber wer weiß), ist hier etwas sicher, solange sich die iphone-hardware nicht ändert (so dass ihr code immer für die iphones funktioniert, die gerade da draußen sind):
#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif
Setzen Sie das an einen geeigneten Ort und geben Sie dann vor, dass die TARGET_*
-Konstanten korrekt definiert wurden.
Funktioniert für Swift 4
und Xcode 9.4.1
Verwenden Sie diesen Code:
#if targetEnvironment(simulator)
// Simulator
#else
// Device
#endif
Für Swift 4.2/xCode 10
Ich habe eine Erweiterung für UIDevice erstellt, so dass ich leicht fragen kann, ob der Simulator läuft.
// 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
}
}
In meiner AppDelegate benutze ich zum Beispiel diese Methode, um zu entscheiden, ob eine Registrierung für die Fernbenachrichtigung erforderlich ist, was für den Simulator nicht möglich ist.
// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {
// REGISTER FOR SILENT REMOTE NOTIFICATION
application.registerForRemoteNotifications()
}
Hat jemand die Antwort als gegeben angesehen hier ?
Ich denke, das Ziel-c-Äquivalent wäre
+ (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);
}
}
Um alle Arten von "Simulatoren" aufzunehmen
NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
// we are running in a simulator
}
Mit Swift 4.2 (Xcode 10) können wir dies tun
#if targetEnvironment(simulator)
//simulator code
#else
#warning("Not compiling for simulator")
#endif
/// Gibt true zurück, wenn der Simulator und kein Gerät vorhanden ist
public static var isSimulator: Bool {
#if (Arch(i386) || Arch(x86_64)) && os(iOS)
return true
#else
return false
#endif
}
wenn nichts funktioniert hat, probiere es aus
public struct Platform {
public static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
}
}
Apple hat die Unterstützung für die Überprüfung der App für den Simulator mit folgenden Optionen hinzugefügt:
#if targetEnvironment(simulator)
let DEVICE_IS_SIMULATOR = true
#else
let DEVICE_IS_SIMULATOR = false
#endif
Meine Antwort basiert auf der Antwort von @Daniel Magnusson und den Kommentaren von @Nuthatch und @ n.Drake. und ich schreibe es, um einige Zeit für Swift-Benutzer zu sparen, die ab iOS9 arbeiten.
Das hat bei mir funktioniert:
if UIDevice.currentDevice().name.hasSuffix("Simulator"){
//Code executing on Simulator
} else{
//Code executing on Device
}
Swift 4 Lösung
static let isSimulator: Bool = {
return TARGET_OS_SIMULATOR == 1
}()
TARGET_OS_SIMULATOR
befindet sich in der Darwin.TargetConditionals.Swift
-Datei.