Xcode / iOS: ¿Cómo determinar si el código se está ejecutando en la construcción DEBUG / RELEASE?

241

Estoy creando una aplicación que procesa datos confidenciales de tarjetas de crédito.

Si mi código se está ejecutando en modo de depuración, quiero registrar estos datos en la consola y hacer algunos volcados de archivos.

Sin embargo, en la versión final de la tienda de aplicaciones (es decir, cuando se ejecuta en modo de lanzamiento) es esencial que todo esto esté deshabilitado (peligro de seguridad).

Intentaré responder a mi pregunta lo mejor que pueda; entonces la pregunta se convierte en '¿Es esta ruta de solución la mejor o la mejor manera de hacerlo?'

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

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

Respuestas:

248

Verifique la configuración de compilación de su proyecto en 'Apple LLVM - Preprocesamiento', 'Macros de preprocesador' para la depuración para asegurarse de que DEBUGse está configurando; haga esto seleccionando el proyecto y haciendo clic en la pestaña de configuración de compilación. Busque DEBUGy observe si efectivamente DEBUGse está configurando.

Pero presta atención. Puede ver que DEBUG ha cambiado a otro nombre de variable como DEBUG_MODE.

Configuración de la pestaña Configuración de la configuración de mi proyecto

luego condicionalmente codifique para DEPURAR en sus archivos fuente

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif
Damo
fuente
Gracias por su respuesta, si trato de hacer esto: #ifdef DEBUG NSLog@("Something");#else//#endifesto no funciona. ¿Cómo puedo inicializar un botón o registrar algo en la consola, por favor, puedes editar tu pregunta?
Malloc
¿Qué pasa en Swift?
technophyle
¿Puedo cambiar esta macro programáticamente en tiempo de ejecución? Quiero habilitar un botón que cambie a las API de producción. En ese botón, quiero cambiar DEBUG a 0 y mostrar el mensaje que el usuario necesita para reiniciar la aplicación. Entonces, la próxima vez usará API de producción.
Hiren Prajapati
130

Para una solución en Swift, consulte este hilo en SO.

Básicamente, la solución en Swift se vería así:

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

Además, deberá establecer el DEBUGsímbolo en la Swift Compiler - Custom Flagssección para la Other Swift Flagsclave a través de una -D DEBUGentrada. Vea la siguiente captura de pantalla para ver un ejemplo:

ingrese la descripción de la imagen aquí

Jeehut
fuente
1
¿Dónde encuentro Swift Compiler - Custom Flags?
Confile
2
@confile: He adjuntado una captura de pantalla que debería aclarar dónde encontrar. ¡Espero eso ayude!
Jeehut
1
¡Recuerde que esto debe definirse para el marco / extensión específico que lo usa! Entonces, si tiene una extensión de teclado / hoy, defínalo allí. Si tiene algún otro tipo de marco lo mismo. Esto solo podría ser necesario si el objetivo principal es el objetivo c ...
Warpzit
gracias, parece que la Other Swift Flagsclave no aparecerá a menos que seleccione Ally combinedsuperior
Oscar Zhang
¡Gracias! Esto es lo que me faltaba. Lo tenía configurado para Clang pero no Swift.
hojaldre
90

Apple ya incluye una DEBUGbandera en las compilaciones de depuración, por lo que no necesita definir la suya.

Es posible que también desee considerar la redefinición NSLogde una operación nula cuando no esté en DEBUGmodo, de esa manera su código será más portátil y simplemente puede usar NSLogdeclaraciones regulares :

//put this in prefix.pch

#ifndef DEBUG
#undef NSLog
#define NSLog(args, ...)
#endif
Nick Lockwood
fuente
33

La mayoría de las respuestas dijeron que cómo configurar #ifdef DEBUG y ninguno de ellos decía cómo determinar la compilación de depuración / liberación.

Mi opinión:

  1. Editar esquema -> ejecutar -> configuración de compilación: elija depurar / liberar. Puede controlar el simulador y el estado del código de su iPhone de prueba.

  2. Editar esquema -> archivo -> configuración de compilación: elija depurar / liberar. Puede controlar la aplicación del paquete de prueba y el estado del código de la aplicación App Store. ingrese la descripción de la imagen aquí

Qun Li
fuente
Respuesta premiada !!! Me ayuda a identificar mi problema. En mi caso, mantuve el Archivemodo Debugy envié la aplicación a la tienda de aplicaciones. Al verificar el resultado después de la descarga de la aplicación de iTunes, simplemente no funciona. Así que asegúrese de que DEBUG/RELEASEsolo funcione cuando se selecciona el modo respectivo en Build/Run/Archive.
Bhavin_m
13

Swift y Xcode 10+

#if DEBUGpasará CUALQUIER desarrollo, compilación ad-hoc, dispositivo o simulador. Solo es falso para las compilaciones de App Store y TestFlight.

Ejemplo:

#if DEBUG
   print("Not App Store build")
#else
   print("App Store build")
#endif
Kirill Kudaev
fuente
8

La respuesta de zitao xiong está bastante cerca de lo que uso; También incluyo el nombre del archivo (quitando la ruta de ARCHIVO ).

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

En xcode 7, hay un campo en Apple LLVM 7.0: preprocesamiento , que se llama " Macros de preprocesadores no utilizados en precompilados ... "? Puse DEBUG delante de Debug y funciona para mí usando el siguiente código:

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

Solo una idea más para detectar:

DebugMode.h

#import <Foundation/Foundation.h>

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

DebugMode.m

#import "DebugMode.h"

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

agregar al archivo de puente de encabezado:

#include "DebugMode.h"

uso:

DebugMode.isDebug()

No es necesario escribir algo dentro de las banderas rápidas de las propiedades del proyecto.

Vyacheslav
fuente
1

No estoy seguro si respondí tu pregunta, tal vez podrías probar este código:

#ifdef DEBUG
#define DLOG(xx, ...)  NSLog( \
    @"%s(%d): " \
    xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ \  
    )
#else
#define DLOG(xx, ...)  ((void)0)
#endif 
Zitao Xiong
fuente
¿Podría explicar exactamente qué está haciendo esa definición? Se ve bien, pero no lo entiendo del todo. X por lo general indica un Apple reservado macro, mientras que PRETTY_FUNCTION indica generó algo de usuario, por lo que el resultado es confuso
P i
2
xx es una cadena de formato, puede usar lo que quiera, si es idéntico a la cadena anterior. Puede usar FUNCTION , pero PRETTY_FUNCTION imprime nombres de métodos Objective-C. Este enlace lo explica muy bien.
Zitao Xiong