Xcode / iOS: Comment déterminer si le code s'exécute dans la version DEBUG / RELEASE?

241

Je crée une application qui traite les données sensibles des cartes de crédit.

Si mon code s'exécute en mode débogage, je veux enregistrer ces données sur la console et effectuer des vidages de fichiers.

Cependant, sur la version finale de l'appstore (c'est-à-dire lorsqu'elle fonctionne en mode release), il est essentiel que tout cela soit désactivé (risque de sécurité)!

Je vais essayer de répondre à ma question du mieux que je peux; la question devient donc: «Cette voie de solution est-elle la bonne ou la meilleure façon de le faire?

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

#if( IS_DEBUG )  
#define MYLog(args...) NSLog(args)  
#else  
#define MYLog(args...)  
#endif  
P i
la source

Réponses:

248

Vérifiez les paramètres de construction de votre projet sous `` Apple LLVM - Prétraitement '', `` Macros de préprocesseur '' pour le débogage afin de vous assurer qu'il DEBUGest défini.Faites-le en sélectionnant le projet et en cliquant sur l'onglet Paramètres de construction. Recherchez DEBUGet regardez pour voir si la DEBUGconfiguration est effective .

Faites attention cependant. Vous pouvez voir DEBUG remplacé par un autre nom de variable tel que DEBUG_MODE.

Onglet Paramètres de construction des paramètres de mon projet

puis codez conditionnellement pour DEBUG dans vos fichiers source

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif
Damo
la source
Merci pour votre réponse, si j'essaie de faire comme ça:, #ifdef DEBUG NSLog@("Something");#else//#endifcela ne fonctionne pas. Comment puis-je initialiser un bouton ou enregistrer quelque chose sur la console, pouvez-vous modifier votre question?
Malloc
Et Swift?
technophyle
puis-je modifier cette macro par programme au moment de l'exécution? Je souhaite activer un bouton qui passe aux API de production. Sur ce bouton, je veux changer DEBUG en 0 et afficher le message dont l'utilisateur a besoin pour redémarrer l'application. La prochaine fois, il utilisera des API de production.
Hiren Prajapati
130

Pour une solution dans Swift, veuillez vous référer à ce fil sur SO.

Fondamentalement, la solution dans Swift ressemblerait à ceci:

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

De plus, vous devrez définir le DEBUGsymbole dans la Swift Compiler - Custom Flagssection de la Other Swift Flagsclé via une -D DEBUGentrée. Voir la capture d'écran suivante pour un exemple:

entrez la description de l'image ici

Jeehut
la source
1
Où puis-je trouver Swift Compiler - Custom Flags?
confile le
2
@confile: J'ai joint une capture d'écran qui devrait indiquer clairement où trouver. J'espère que ça aide!
Jeehut du
1
N'oubliez pas que cela doit être défini pour le cadre / l'extension spécifique qui l'utilise! Donc, si vous avez une extension clavier / aujourd'hui, définissez-la ici. Si vous avez un autre type de framework, c'est la même chose. Cela pourrait être nécessaire uniquement si la cible principale est l'objectif c ...
Warpzit
merci, il semble que la Other Swift Flagsclé n'apparaisse que si vous sélectionnez Allet combinedau
Oscar Zhang
Merci! C'est ce qui me manquait. Je l'avais réglé pour Clang mais pas Swift.
bugloaf
90

Apple inclut déjà un DEBUGindicateur dans les versions de débogage, vous n'avez donc pas besoin de définir la vôtre.

Vous pouvez également envisager de redéfinir simplement NSLogune opération nulle lorsqu'il n'est pas en DEBUGmode, de cette façon, votre code sera plus portable et vous pouvez simplement utiliser des NSLoginstructions régulières :

//put this in prefix.pch

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

La plupart des réponses indiquaient comment définir #ifdef DEBUG et aucune d'entre elles ne disait comment déterminer la version de débogage / version.

Mon avis:

  1. Modifier le schéma -> exécuter -> configurer la configuration: choisissez débogage / libération. Il peut contrôler le simulateur et l'état du code de votre iPhone de test.

  2. Modifier le schéma -> archiver -> configurer la configuration: choisissez débogage / libération. Il peut contrôler l'application du package de test et l'état du code de l'application App Store. entrez la description de l'image ici

Qun Li
la source
Réponse récompensée !!! cela m'aide à identifier mon problème. Dans mon cas, j'avais conservé le Archivemode Debuget soumis l'application à l'App Store. Lorsque vous vérifiez le résultat après le téléchargement de l'application depuis iTunes, cela ne fonctionne tout simplement pas. Assurez-vous donc que cela DEBUG/RELEASEne fonctionne que lorsque le mode respectif est sélectionné dans Build/Run/Archive.
Bhavin_m
13

Swift et Xcode 10+

#if DEBUGpassera dans TOUT développement / build ad hoc, appareil ou simulateur. Ce n'est faux que pour les versions App Store et TestFlight.

Exemple:

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

la réponse de zitao xiong est assez proche de ce que j'utilise; J'inclus également le nom du fichier (en supprimant le chemin du FICHIER ).

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

Dans xcode 7, il y a un champ sous Apple LLVM 7.0 - prétraitement , qui s'appelle " Macros de préprocesseurs non utilisées en précompilé ... "? J'ai mis DEBUG devant Debug et cela fonctionne pour moi en utilisant le code ci-dessous:

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

Encore une idée à détecter:

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

ajouter dans le fichier de pont d'en-tête:

#include "DebugMode.h"

usage:

DebugMode.isDebug()

Il n'est pas nécessaire d'écrire quelque chose dans les drapeaux rapides des propriétés du projet.

Vyacheslav
la source
1

Je ne sais pas si je vous ai répondu à la question, peut-être pourriez-vous essayer ce code:

#ifdef DEBUG
#define DLOG(xx, ...)  NSLog( \
    @"%s(%d): " \
    xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ \  
    )
#else
#define DLOG(xx, ...)  ((void)0)
#endif 
Zitao Xiong
la source
Pourriez-vous expliquer exactement ce que fait cette définition? Ça a l'air bien, mais je ne comprends pas très bien. X indique généralement une macro réservée à Apple, tandis que PRETTY_FUNCTION indique quelque chose généré par l'utilisateur, donc le résultat est déroutant
P i
2
xx est une chaîne de format, vous pouvez utiliser ce que vous voulez, s'il est identique à la chaîne précédente. Vous pouvez utiliser FUNCTION , mais PRETTY_FUNCTION affiche les noms des méthodes Objective-C. ce lien l' explique très bien.
Zitao Xiong