iPhone 模拟器 - 如何检测应用程序何时在模拟器上运行(因此可以设置测试数据)?

Posted

技术标签:

【中文标题】iPhone 模拟器 - 如何检测应用程序何时在模拟器上运行(因此可以设置测试数据)?【英文标题】:iPhone simulator - how to detect when app is running on simulator (so can setup test data)? 【发布时间】:2011-07-04 13:49:28 【问题描述】:

在我的 iPhone 应用程序代码中,任何可以告诉我如何操作的示例代码:

    如何检测应用程序是否刚刚部署以运行到模拟器(而不是设备)[如果“已部署”不可用,则仅检测应用程序何时在模拟器上运行,而不是设备) 我将在我的 iPhone 应用程序代码中的哪个位置放置在模拟器中设置我的测试数据的行 - 这说明我希望每次重新编译并推送到模拟器时都能有效地清除/重新安装测试数据(但是我真的不希望在模拟器中使用应用程序期间运行此代码 - 例如应该能够在模拟器中交换应用程序然后当我在模拟器中再次启动我的应用程序时它不应该运行数据设置代码

关于如何隐藏在模拟器上管理此测试数据的任何其他更好的建议都会很好。这里的背景是我在谈论日历中的测试数据(例如使用 Event Kit),所以当我部署到我的设备时,我不想让应用程序将日历项目放入我的 iPhone(抱歉 - 只有 1 个人iPhone在这里)。

【问题讨论】:

【参考方案1】:

我显然确实使用过类似的东西......

#import <TargetConditionals.h>

#if TARGET_IPHONE_SIMULATOR

// Simulator specific code

#else // TARGET_IPHONE_SIMULATOR

// Device specific code

#endif // TARGET_IPHONE_SIMULATOR

关于你的第二个问题......这样的事情应该对你有所帮助。在您的应用委托中:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
  if ( ! [[NSUserDefaults standardUserDefaults] boolForKey:@"initialized"] ) 
    // Setup stuff
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"initialized"];
  

  ... your code ...

【讨论】:

谢谢 - 所以关于 2:我可以在代码中的哪个位置(即哪种方法)放置此设置代码,以便它仅在我第一次启动应用程序时运行?即,如果我跳到 App B 然后又回到我的 App,它就不会再次运行。但是,我假设当我关闭应用程序(双击 iPhone 按钮等)时,当我再次单击应用程序时,这将被归类为第一次运行。希望这是有道理的。 刚刚编辑了我的答案。您需要一些标志来了解您的应用程序是否已初始化。我确实向您展示了如何使用用户默认值执行此操作,但是有很多方法可以执行此操作。 好的,谢谢 - 所以你是在暗示 iPhone 生命周期模型(即状态、消息)中没有任何东西可以固有地区分?即您几乎必须自己编写代码? - 另外,如果您确实(例如在模拟器上)删除了应用程序(即杀死我猜的进程),那么这段代码会在这里工作吗?即它真的会删除 NSUserDefaults 吗? 当您从模拟器/设备中删除您的应用程序时,NSUserDefaults 将被删除。 2015 年更新:TARGET_IPHONE_SIMULATOR 现在已弃用,而应使用 TARGET_OS_SIMULATOR【参考方案2】:

如果您想检查运行时(而不是使用 # 编译器宏编译时间),请使用以下代码:

UIDevice *currentDevice = [UIDevice currentDevice];
if ([currentDevice.model rangeOfString:@"Simulator"].location == NSNotFound) 
    //running on device
 else  
    // running in Simulator

另请参阅此问题: How can I programmatically determine if my app is running in the iphone simulator?

【讨论】:

这不再正确。 currentDevice.model 现在将返回“iPhone”或“iPad”。我猜这在最近的 SDK 更新中有所改变。我们使用 sysctlbyname("hw.machine") 并将返回值与 x86_64 进行比较。【参考方案3】:

对我有用的代码块:

#if defined(__i386__)  || defined(__x86_64__)
    /* Run code if in Simulator */
#else
    /* Run code if in device */
#end

我注意到__i386__ 不适用于 iPhone 6 模拟器,所以我添加了 x86_64

【讨论】:

使用这种技术是脆弱的,因为每当 Apple 更新他们的平台时,它都需要更新。 robertvojta 指定的技术更可靠。 确实如此。但更易于使用,因为您不需要导入。此外,Apple 添加新平台并不常见。 我猜它在 M1 Macs 中不再起作用了。请更新您的答案。【参考方案4】:

斯威夫特 5:

TARGET_OS_SIMULATOR 在 Swift 5 中不起作用。targetEnvironment(simulator) 起作用,如下所示:

#if targetEnvironment(simulator)
// code to run if running on simulator
#else
// code to run if not running on simulator
#endif

Reference

【讨论】:

以上是关于iPhone 模拟器 - 如何检测应用程序何时在模拟器上运行(因此可以设置测试数据)?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 iPhone MPMoviePlayer 控件何时出现/消失?

如何在 iPhone 模拟器上打开位置检测

iPhone:如何使用 AVAudioPlayer 检测 Iphone/Ipod 音量级别

如何检测 iPhone 上的内存泄漏?

iPhone 检测到用户向上移动了他们的设备

sh 检测Android模拟器何时完全启动