正如问题所述,我主要想知道我的代码是否在模拟器中运行,并且也想知道正在运行或模拟的具体 iPhone 版本。
编辑:我在问题名称中添加了“以编程方式”,我的问题的重点是能够根据正在运行的版本/模拟器动态包含/排除代码,因此我真正需要的是类似于预处理器指令的东西,可以为我提供这些信息。
正如问题所述,我主要想知道我的代码是否在模拟器中运行,并且也想知道正在运行或模拟的具体 iPhone 版本。
编辑:我在问题名称中添加了“以编程方式”,我的问题的重点是能够根据正在运行的版本/模拟器动态包含/排除代码,因此我真正需要的是类似于预处理器指令的东西,可以为我提供这些信息。
已经有人问过这个问题,但标题不同。
在编译 iPhone 应用程序时 Xcode 设置了哪些 #define
我会重复我的答案:
在 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]
。 - user102008[model hasSuffix:@"Simulator"]
。但这个方法对于iPad模拟器不起作用 :) - Nuthatch现在在Swift中有更好的方法。
从Xcode 9.3及更高版本开始,您可以使用#if targetEnvironment(simulator)
进行检查。
#if targetEnvironment(simulator)
//Your simulator code
#endif
最好的方法是:
#if TARGET_IPHONE_SIMULATOR
而不是
#ifdef TARGET_IPHONE_SIMULATOR
由于它总是定义的:0或1
对于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
会更好。 - DawnSong[[UIDevice currentDevice] model]
该代码将根据应用程序运行的位置返回“iPhone Simulator”或“iPhone”。
编译时
然而,您想要使用编译时定义。为什么?因为您严格编译应用程序以在模拟器内部或设备上运行。苹果公司创建了一个名为TARGET_IPHONE_SIMULATOR
的定义。因此,让我们看一下代码:
#if TARGET_IPHONE_SIMULATOR
NSLog(@"Running in Simulator - no app store or giro");
#endif
针对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()
}
TARGET_IPHONE_SIMULATOR
宏(假设你正在编写iOS应用,不需要包含任何其他头文件)即可。TARGET_OS_IPHONE
,但在实际设备和模拟器上运行时返回相同的值(1),这就是为什么我建议使用 TARGET_IPHONE_SIMULATOR
的原因。
__x86_64__
(iPhone模拟器)和__arm64__
(iPhone设备)。 - rustyMagnet