Xcode / iOS:如何确定代码是否正在DEBUG / RELEASE构建中运行?


241

我正在制作一个处理敏感信用卡数据的应用程序。

如果我的代码在调试模式下运行,我想将此数据记录到控制台并进行一些文件转储。

但是,在最终的Appstore版本(即以发布模式运行时)上,必须禁用所有这些功能(安全隐患)!

我将尽力回答我的问题;因此问题就变成“此解决方案路径是正确的还是最佳的实现方式?”

// add `IS_DEBUG=1` to your debug build preprocessor settings  

#if( IS_DEBUG )  
#define MYLog(args...) NSLog(args)  
#else  
#define MYLog(args...)  
#endif  

Answers:


247

在“ Apple LLVM-预处理”,“预处理器宏”下检查项目的构建设置以进行调试,以确保DEBUG已设置-通过选择项目并单击构建设置选项卡来执行此操作。搜索DEBUG并查看是否确实DEBUG已设置。

不过要注意。您可能会看到DEBUG更改为另一个变量名,例如DEBUG_MODE。

我的项目设置的“构建设置”选项卡

然后在源文件中有条件地为DEBUG编码

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif

感谢您的回答,如果我尝试这样做:#ifdef DEBUG NSLog@("Something");#else//#endif,则不起作用。请问如何初始化按钮或将某些信息记录到控制台,您可以编辑问题吗?
Malloc 2012年

在Swift中呢?
technophyle

我可以在运行时以编程方式更改此宏吗?我想启用一个切换到生产API的按钮。在该按钮上,我想将DEBUG更改为0并显示用户需要重新启动应用程序的消息。因此,下一次它将使用生产API。
Hiren Prajapati

130

有关Swift中的解决方案,请参阅SO 上的该线程

基本上,Swift中解决方案如下所示:

#if DEBUG
    println("I'm running in DEBUG mode")
#else
    println("I'm running in a non-DEBUG mode")
#endif

另外,您将需要通过输入在密钥部分设置DEBUG符号。有关示例,请参见以下屏幕截图:Swift Compiler - Custom FlagsOther Swift Flags-D DEBUG

在此处输入图片说明


1
在哪里可以找到Swift编译器-自定义标志?

2
@confile:我已经附上了一个屏幕截图,该屏幕截图应明确说明在哪里可以找到。希望能帮助到你!
Jeehut 2015年

1
请记住,这需要为使用它的特定框架/扩展定义!因此,如果您有键盘/今天的扩展名,请在此处进行定义。如果您有其他某种框架,则相同。如果主要目标是目标C ...这可能仅仅是必要的
Warpzit

谢谢,Other Swift Flags除非您选择All并选择combined以上键,否则似乎不会显示密钥
Oscar Zhang

谢谢!这就是我所缺少的。我为Clang设置了它,但没有为Swift设置。
bugloaf

90

Apple已DEBUG在调试版本中包含一个标志,因此您无需定义自己的标志。

您可能还想考虑NSLog在不处于DEBUG模式下时仅将其重新定义为空操作,这样您的代码将更加可移植,您可以只使用常规NSLog语句:

//put this in prefix.pch

#ifndef DEBUG
#undef NSLog
#define NSLog(args, ...)
#endif

33

大多数答案都说过如何设置#ifdef DEBUG,但没有一个回答如何确定调试/发布版本。

我的看法:

  1. 编辑方案->运行->构建配置:选择debug / release。它可以控制模拟器和您测试iPhone的代码状态。

  2. 编辑方案->存档->构建配置:选择debug / release。它可以控制测试包应用程序和App Store应用程序的代码状态。 在此处输入图片说明


获奖答案!!!它可以帮助我确定问题所在。就我而言,我将Archive模式保留为该模式,Debug然后将其提交给应用商店。从iTunes下载应用程序后检查结果时,它根本不起作用。因此,请确保DEBUG/RELEASE仅当在中选择相应的模式时才起作用Build/Run/Archive
Bhavin_m

13

SwiftXcode 10+

#if DEBUG将通过任何开发/临时构建,设备或模拟器。对于App Store和TestFlight构建而言,这只是错误的。

例:

#if DEBUG
   print("Not App Store build")
#else
   print("App Store build")
#endif

8

zitao xiong的答案与我使用的答案非常接近;我还包括了文件名(通过剥离FILE的路径)。

#ifdef DEBUG
    #define NSLogDebug(format, ...) \
    NSLog(@"<%s:%d> %s, " format, \
    strrchr("/" __FILE__, '/') + 1, __LINE__, __PRETTY_FUNCTION__, ## __VA_ARGS__)
#else
    #define NSLogDebug(format, ...)
#endif

7

在xcode 7中,Apple LLVM 7.0下有一个字段-预处理,它称为“ 未在预编译中使用的预处理器宏... ”?我把DEBUG前面调试,它通过使用下面的代码为我工作:

#ifdef DEBUG
    NSString* const kURL = @"http://debug.com";
#else
    NSString* const kURL = @"http://release.com";
#endif

4

还有一个想法可以发现:

调试模式

#import <Foundation/Foundation.h>

@interface DebugMode: NSObject
    +(BOOL) isDebug;
@end

调试模式

#import "DebugMode.h"

@implementation DebugMode
+(BOOL) isDebug {
#ifdef DEBUG
    return true;
#else
    return false;
#endif
}
@end

添加到头桥文件:

#include "DebugMode.h"

用法:

DebugMode.isDebug()

不需要在项目属性swift标志中编写内容。


1

不知道我是否回答了您的问题,也许您可​​以尝试以下代码:

#ifdef DEBUG
#define DLOG(xx, ...)  NSLog( \
    @"%s(%d): " \
    xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ \  
    )
#else
#define DLOG(xx, ...)  ((void)0)
#endif 

您能详细说明一下定义在做什么吗?看起来很整洁,但我不太明白。 X通常表示Apple保留的宏,而PRETTY_FUNCTION表示用户生成的东西,因此结果令人困惑
P i

2
xx是格式字符串,如果与前面的字符串相同,则可以使用任何所需的格式。您可以使用FUNCTION,但是PRETTY_FUNCTION打印Objective-C方法名称。这个链接很好地解释了。
Zitao Xiong
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.