正如问题所指出的那样,我主要想知道我的代码是否正在模拟器中运行,但也想知道正在运行或正在模拟的特定iphone版本。
编辑:我在问题名称中添加了“以编程方式”一词。我的问题的关键是能够根据正在运行的版本/模拟器动态地包含/排除代码,因此我真的在寻找可以提供此信息的类似预处理程序指令的东西。
正如问题所指出的那样,我主要想知道我的代码是否正在模拟器中运行,但也想知道正在运行或正在模拟的特定iphone版本。
编辑:我在问题名称中添加了“以编程方式”一词。我的问题的关键是能够根据正在运行的版本/模拟器动态地包含/排除代码,因此我真的在寻找可以提供此信息的类似预处理程序指令的东西。
Answers:
已经问过,但标题却大不相同。
我将从那里重复我的回答:
在SDK文档的“有条件地编译源代码”下
相关定义是TARGET_OS_SIMULATOR,该定义在iOS框架的/usr/include/TargetConditionals.h中定义。在较早版本的工具链上,您必须编写:
#include "TargetConditionals.h"
但这在当前(Xcode 6 / iOS8)工具链上不再需要。
因此,例如,如果要检查设备是否正在运行,则应执行
#if TARGET_OS_SIMULATOR
// Simulator-specific code
#else
// Device-specific code
#endif
取决于哪个适合您的用例。
据称这是正式工作。
#if TARGET_IPHONE_SIMULATOR
NSString *hello = @"Hello, iPhone simulator!";
#elif TARGET_OS_IPHONE
NSString *hello = @"Hello, device!";
#else
NSString *hello = @"Hello, unknown target!";
#endif
此代码将告诉您是否正在模拟器中运行。
#ifdef __i386__
NSLog(@"Running in the simulator");
#else
NSLog(@"Running on a device");
#endif
不是预处理程序指令,但这是我遇到这个问题时要寻找的东西。
NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}
[model compare:iPhoneSimulator] == NSOrderedSame
应该写为[model isEqualToString:iPhoneSimulator]
[model hasSuffix:@"Simulator"]
如果您只关心一般的“模拟器”,而不关心iPhone或iPad特别。此答案不适用于iPad模拟器:)
name
而不要model
Simulator
在自己的设备名称字
现在有更好的方法!
从Xcode 9.3 beta 4开始,您可以使用#if targetEnvironment(simulator)
进行检查。
#if targetEnvironment(simulator)
//Your simulator code
#endif
UPDATE
Xcode 10和iOS 12 SDK也支持此功能。
在Swift的情况下,我们可以实现以下
我们可以创建允许您创建结构化数据的结构
struct Platform {
static var isSimulator: Bool {
#if targetEnvironment(simulator)
// We're on the simulator
return true
#else
// We're on a device
return false
#endif
}
}
然后,如果我们想检测Swift中是否正在为设备或模拟器构建应用程序,则。
if Platform.isSimulator {
// Do one thing
} else {
// Do the other
}
#if #else #endif
会更好。
所有这些答案都是好的,但是由于它并不能澄清编译检查和运行时检查,因此它使我这样的新手感到困惑。预处理程序早于编译时间,但我们应该使其更清晰
这篇博客文章显示了如何检测iPhone模拟器?清楚地
运行
首先,让我们简短地讨论一下。UIDevice已为您提供有关设备的信息
[[UIDevice currentDevice] model]
会根据应用程序的运行位置返回“ iPhone模拟器”或“ iPhone”。
编译时间
但是,您要使用的是编译时定义。为什么?因为您严格编译应用程序以使其可以在模拟器内部或设备上运行。苹果公司将其定义为 TARGET_IPHONE_SIMULATOR
。因此,让我们看一下代码:
#if TARGET_IPHONE_SIMULATOR
NSLog(@"Running in Simulator - no app store or giro");
#endif
[[UIDevice currentDevice] model]
也将返回iPhone
而不是iPhone Simulator
。因此,我认为这不是最佳方法。
先前的答案有些过时。我发现您需要做的就是查询TARGET_IPHONE_SIMULATOR
宏(无需包含任何其他头文件(假设您正在为iOS编写代码))。
我尝试过,TARGET_OS_IPHONE
但是在实际的设备和模拟器上运行时它返回了相同的值(1),这就是为什么我建议改用它的原因TARGET_IPHONE_SIMULATOR
。
我有同样的问题,无论是TARGET_IPHONE_SIMULATOR
和TARGET_OS_IPHONE
总是定义,并设置为1。皮特的解决方案作品,当然,但如果你曾经发生的基础上比Intel以外的东西(不太可能,但谁知道),这里的东西是安全的,因为只要iphone硬件没有变化(因此您的代码将始终适用于当前在那里的iphone):
#if defined __arm__ || defined __thumb__
#undef TARGET_IPHONE_SIMULATOR
#define TARGET_OS_IPHONE
#else
#define TARGET_IPHONE_SIMULATOR 1
#undef TARGET_OS_IPHONE
#endif
将其放在方便的位置,然后假装TARGET_*
常量定义正确。
有没有人考虑过这里提供的答案?
我想与Objective-C等效
+ (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);
}
}
对于Swift 4.2 / xCode 10
我在UIDevice上创建了一个扩展,因此我可以轻松地询问模拟器是否正在运行。
// 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
}
}
例如,在我的AppDelegate中,我使用此方法来确定是否需要注册远程通知,这对于模拟器是不可能的。
// CHECK FOR REAL DEVICE / OR SIMULATOR
if UIDevice.isSimulator() == false {
// REGISTER FOR SILENT REMOTE NOTIFICATION
application.registerForRemoteNotifications()
}
包括所有类型的“模拟器”
NSString *model = [[UIDevice currentDevice] model];
if([model rangeOfString:@"Simulator" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
// we are running in a simulator
}
-[NSString containsString]
呢?
我的答案基于@Daniel Magnusson的答案以及@Nuthatch和@ n.Drake的评论。我编写它的目的是为在iOS9及更高版本上工作的迅速用户节省一些时间。
这对我有用:
if UIDevice.currentDevice().name.hasSuffix("Simulator"){
//Code executing on Simulator
} else{
//Code executing on Device
}
Simulator
在自己的设备名称字
UIDevice.current.name
报告了运行模拟器的计算机的名称(现在通常是类似于“ Simon的MacBook Pro”之类的名称),因此测试变得不可靠。我仍在寻找一种干净的方法来修复它。
///如果其模拟器而不是设备,则返回true
public static var isSimulator: Bool {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return true
#else
return false
#endif
}
如果没有任何效果,请尝试此
public struct Platform {
public static var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0 // Use this line in Xcode 7 or newer
}
}
我认为,答案(在上方显示并在下方重复):
NSString *model = [[UIDevice currentDevice] model];
if ([model isEqualToString:@"iPhone Simulator"]) {
//device is simulator
}
是最佳答案,因为它显然是在运行时执行的,而不是作为编译指令的。