Xcode / iOS: Wie kann festgestellt werden, ob Code im DEBUG / RELEASE-Build ausgeführt wird?

241

Ich mache eine App, die sensible Kreditkartendaten verarbeitet.

Wenn mein Code im Debug-Modus ausgeführt wird, möchte ich diese Daten in der Konsole protokollieren und einige Datei-Dumps erstellen.

Bei der endgültigen Appstore-Version (dh wenn sie im Release-Modus ausgeführt wird) ist es jedoch wichtig, dass all dies deaktiviert ist (Sicherheitsrisiko)!

Ich werde versuchen, meine Frage so gut wie möglich zu beantworten. Die Frage lautet also: Ist dieser Lösungsweg der richtige oder beste Weg, dies zu tun?

// 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
quelle

Antworten:

247

Überprüfen Sie die Build-Einstellungen Ihres Projekts unter "Apple LLVM - Vorverarbeitung", "Präprozessor-Makros" auf Debugging, um sicherzustellen, dass DEBUGsie festgelegt werden. Wählen Sie dazu das Projekt aus und klicken Sie auf die Registerkarte "Build-Einstellungen". Suchen DEBUGund suchen Sie, ob tatsächlich DEBUGeingestellt wird.

Pass aber auf. Möglicherweise wird DEBUG in einen anderen Variablennamen wie DEBUG_MODE geändert.

Registerkarte "Build-Einstellungen" meiner Projekteinstellungen

dann bedingter Code für DEBUG in Ihren Quelldateien

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif
Damo
quelle
Vielen Dank für Ihre Antwort, wenn ich versuche, so zu machen : #ifdef DEBUG NSLog@("Something");#else//#endif, funktioniert das nicht. Wie kann ich eine Schaltfläche initialisieren oder etwas in der Konsole protokollieren? Können Sie Ihre Frage bearbeiten?
Malloc
Was ist mit in Swift?
Technophyle
Kann ich dieses Makro zur Laufzeit programmgesteuert ändern? Ich möchte eine Schaltfläche aktivieren, die zu Produktions-APIs wechselt. Auf dieser Schaltfläche möchte ich DEBUG auf 0 ändern und die Meldung anzeigen, die der Benutzer zum Neustart der App benötigt. Beim nächsten Mal werden also Produktions-APIs verwendet.
Hiren Prajapati
130

Eine Lösung in Swift finden Sie in diesem Thread zu SO.

Grundsätzlich würde die Lösung in Swift folgendermaßen aussehen:

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

Zusätzlich müssen Sie das DEBUGSymbol im Swift Compiler - Custom FlagsAbschnitt für den Other Swift FlagsSchlüssel über einen -D DEBUGEintrag festlegen . Ein Beispiel finden Sie im folgenden Screenshot:

Geben Sie hier die Bildbeschreibung ein

Jeehut
quelle
1
Wo finde ich Swift Compiler - Custom Flags?
Confile
2
@confile: Ich habe einen Screenshot angehängt, der klar machen soll, wo er zu finden ist. Ich hoffe es hilft!
Jeehut
1
Denken Sie daran, dass dies für das spezifische Framework / die Erweiterung definiert werden muss, die es verwenden! Wenn Sie also eine Tastatur / Heute-Erweiterung haben, definieren Sie diese dort. Wenn Sie ein anderes Framework haben, dasselbe. Dies ist möglicherweise nur erforderlich, wenn das Hauptziel das Ziel ist ...
Warpzit
danke, es scheint, dass der Other Swift FlagsSchlüssel erst angezeigt wird, wenn Sie Allund combinedhöher auswählen
Oscar Zhang
Vielen Dank! Das hat mir gefehlt. Ich hatte es auf Clang eingestellt, aber nicht auf Swift.
Bugloaf
90

Apple enthält bereits ein DEBUGFlag in Debug-Builds, sodass Sie kein eigenes definieren müssen.

Möglicherweise möchten Sie auch in Betracht ziehen, nur NSLogeine Nulloperation neu zu definieren , wenn Sie sich nicht im DEBUGModus befinden. Auf diese Weise ist Ihr Code portabler und Sie können einfach reguläre NSLogAnweisungen verwenden:

//put this in prefix.pch

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

Die meisten Antworten besagten, wie #ifdef DEBUG gesetzt werden soll, und keiner von ihnen sagte, wie man den Debug- / Release-Build bestimmt.

Meine Meinung:

  1. Schema bearbeiten -> ausführen -> Konfiguration erstellen: Debug / Release auswählen. Es kann den Simulator und den Codestatus Ihres Test-iPhones steuern.

  2. Schema bearbeiten -> Archiv -> Konfiguration erstellen: Debug / Release wählen. Es kann die Testpaket-App und den Codestatus der App Store-App steuern. Geben Sie hier die Bildbeschreibung ein

Qun Li
quelle
Ausgezeichnete Antwort !!! es hilft mir, mein Problem zu identifizieren. In meinem Fall hatte ich den ArchiveModus beibehalten Debugund die App an den App Store gesendet. Wenn Sie das Ergebnis nach dem Herunterladen der App aus iTunes überprüfen, funktioniert es einfach nicht. Stellen Sie also sicher, dass dies DEBUG/RELEASEnur funktioniert, wenn der entsprechende Modus ausgewählt ist Build/Run/Archive.
Bhavin_m
13

Swift und Xcode 10+

#if DEBUGwird in JEDER Entwicklung / Ad-hoc-Erstellung, jedem Gerät oder Simulator übergeben. Es ist nur für App Store- und TestFlight-Builds falsch.

Beispiel:

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

Die Antwort von zitao xiong kommt meiner Verwendung ziemlich nahe. Ich füge auch den Dateinamen hinzu (indem ich den Pfad von FILE entferne ).

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

In xcode 7 gibt es unter Apple LLVM 7.0 - Vorverarbeitung ein Feld mit dem Namen " Präprozessormakros , die in vorkompilierten Dateien nicht verwendet werden ... "? Ich habe DEBUG vor Debug gestellt und es funktioniert für mich unter Verwendung des folgenden Codes:

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

Nur noch eine Idee zu entdecken:

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

In die Header-Bridge-Datei einfügen:

#include "DebugMode.h"

Verwendung:

DebugMode.isDebug()

Es ist nicht erforderlich, etwas in die schnellen Flags der Projekteigenschaften zu schreiben.

Vyacheslav
quelle
1

Ich bin mir nicht sicher, ob ich Ihre Frage beantwortet habe. Vielleicht könnten Sie diesen Code ausprobieren:

#ifdef DEBUG
#define DLOG(xx, ...)  NSLog( \
    @"%s(%d): " \
    xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ \  
    )
#else
#define DLOG(xx, ...)  ((void)0)
#endif 
Zitao Xiong
quelle
Könnten Sie genau erläutern, was diese Definition tut? Es sieht ordentlich aus, aber ich verstehe es nicht ganz. X Zeigt normalerweise ein von Apple reserviertes Makro an, während PRETTY_FUNCTION etwas anzeigt, das vom Benutzer generiert wurde, sodass das Ergebnis verwirrend ist
P i
2
xx ist eine Formatzeichenfolge. Sie können alles verwenden, was Sie möchten, wenn es mit der vorherigen Zeichenfolge identisch ist. Sie können mit FUNCTION , aber PRETTY_FUNCTION Objective-C - Methode Namen drucken. Dieser Link erklärt es sehr gut.
Zitao Xiong