Xcode / iOS: como determinar se o código está sendo executado na compilação DEBUG / RELEASE?


241

Estou criando um aplicativo que processa dados confidenciais de cartão de crédito.

Se meu código estiver sendo executado no modo de depuração, desejo registrar esses dados no console e fazer alguns despejos de arquivos.

No entanto, na versão final da appstore (ou seja, quando está sendo executada no modo de lançamento), é essencial que tudo isso esteja desativado (risco de segurança)!

Vou tentar responder minha pergunta da melhor maneira possível; então a pergunta se torna: 'Esse caminho da solução é a melhor ou a melhor maneira de fazê-lo?'

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

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

Respostas:


247

Verifique as configurações de compilação do seu projeto em 'Apple LLVM - Pré-processamento', 'Macros de Pré-processador' para depuração para garantir que DEBUGestá sendo definido - faça isso selecionando o projeto e clicando na guia configurações de compilação. Procure DEBUGe veja se realmente DEBUGestá sendo definido.

Preste atenção embora. Você pode ver DEBUG alterado para outro nome de variável, como DEBUG_MODE.

Guia Configurações de compilação das configurações do meu projeto

então codifique condicionalmente DEBUG em seus arquivos de origem

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif

Obrigado pela sua resposta, se eu tentar fazer assim:, #ifdef DEBUG NSLog@("Something");#else//#endifisso não funciona. Como posso inicializar um botão ou registrar algo no console, você pode editar sua pergunta?
Malloc

E em Swift?
technophyle

posso alterar essa macro programaticamente em tempo de execução? Desejo ativar um botão que alterne para APIs de produção. Nesse botão, desejo alterar DEBUG para 0 e exibir a mensagem de que o usuário precisa reiniciar o aplicativo. Então, da próxima vez, ele usará APIs de produção.
Hiren Prajapati

130

Para uma solução em Swift, consulte este tópico no SO.

Basicamente, a solução no Swift ficaria assim:

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

Além disso, você precisará definir o DEBUGsímbolo na Swift Compiler - Custom Flagsseção da Other Swift Flagschave por meio de uma -D DEBUGentrada. Veja a seguinte captura de tela para um exemplo:

insira a descrição da imagem aqui


1
Onde encontro o Swift Compiler - sinalizadores personalizados?
confile 19/09/15

2
@confile: Anexei uma captura de tela que deve deixar claro onde encontrar. Espero que ajude!
Jeehut 20/09/2015

1
Lembre-se de que isso precisa ser definido para a estrutura / extensão específica que a utiliza! Portanto, se você tem uma extensão de teclado / hoje, defina-a lá. Se você tiver algum outro tipo de estrutura, a mesma coisa. Isso só poderia ser necessário se o alvo principal é objetiva c ...
Warpzit

obrigado, parece Other Swift Flagschave não aparecerá a menos que você selecione Alle combinedacima
Oscar Zhang

Obrigado! Isso é o que eu estava perdendo. Eu tinha definido para Clang, mas não para Swift.
bugloaf 28/02

90

A Apple já inclui um DEBUGsinalizador nas compilações de depuração, para que você não precise definir seu próprio.

Você também pode considerar redefinir NSLogpara uma operação nula quando não estiver no DEBUGmodo, para que seu código seja mais portátil e você possa usar apenas NSLoginstruções regulares :

//put this in prefix.pch

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

33

A maioria das respostas disse que como definir #ifdef DEBUG e nenhuma delas diz como determinar a compilação de depuração / lançamento.

Minha opinião:

  1. Edite o esquema -> execute -> configure a configuração: escolha debug / release. Ele pode controlar o simulador e o status do código do seu iPhone de teste.

  2. Esquema de edição -> arquivo morto -> configuração da compilação: escolha depuração / liberação. Ele pode controlar o aplicativo do pacote de teste e o status do código do aplicativo da App Store. insira a descrição da imagem aqui


Resposta premiada !!! isso me ajuda a identificar meu problema. No meu caso, eu mantive o Archivemodo Debuge enviei o aplicativo para a loja de aplicativos. Ao verificar o resultado após o download do aplicativo no iTunes, ele simplesmente não funciona. Portanto, verifique se isso DEBUG/RELEASEfunciona apenas quando o modo respectivo é selecionado Build/Run/Archive.
precisa saber é o seguinte

13

Swift e Xcode 10+

#if DEBUGpassará em QUALQUER desenvolvimento / compilação ad-hoc, dispositivo ou simulador. É apenas falso para as compilações da App Store e do TestFlight.

Exemplo:

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

8

a resposta de zitao xiong está bem próxima do que eu uso; Eu também incluo o nome do arquivo (removendo o caminho de 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

No xcode 7, há um campo no Apple LLVM 7.0 - pré-processamento , chamado " Macros de pré-processadores não usados ​​em pré-compilados ... "? Coloquei DEBUG na frente do Debug e ele funciona para mim usando o código abaixo:

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

4

Apenas mais uma ideia 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

adicione no arquivo de ponte de cabeçalho:

#include "DebugMode.h"

uso:

DebugMode.isDebug()

Não é necessário escrever algo dentro dos sinalizadores rápidos das propriedades do projeto.


1

Não tenho certeza se eu respondi sua pergunta, talvez você possa tentar estes códigos:

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

Você poderia elaborar exatamente o que essa definição está fazendo? Parece legal, mas não entendo direito. X geralmente indica um Apple reservados macro, enquanto PRETTY_FUNCTION indica algo gerado pelo usuário, então o resultado é confuso
P i

2
xx é uma string de formato, você pode usar o que quiser, se for idêntico à string anterior. Você pode usar FUNCTION , mas PRETTY_FUNCTION imprime os nomes dos métodos Objective-C. este link explica muito bem.
Zitao Xiong 31/01
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.