Xcode / iOS: Jak ustalić, czy kod działa w kompilacji DEBUG / RELEASE?

241

Tworzę aplikację, która przetwarza wrażliwe dane karty kredytowej.

Jeśli mój kod działa w trybie debugowania, chcę zalogować te dane do konsoli i wykonać zrzuty plików.

Jednak w ostatecznej wersji sklepu (tj. Gdy działa w trybie wydania) ważne jest, aby wszystko to było wyłączone (zagrożenie bezpieczeństwa)!

Postaram się odpowiedzieć na moje pytanie najlepiej jak potrafię; więc pytanie brzmi: „Czy ta ścieżka rozwiązania jest właściwym, czy najlepszym sposobem na to?”

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

#if( IS_DEBUG )  
#define MYLog(args...) NSLog(args)  
#else  
#define MYLog(args...)  
#endif  
Liczba Pi
źródło

Odpowiedzi:

248

Sprawdź ustawienia kompilacji projektu w „Apple LLVM - Preprocessing”, „Preprocessor Macros” w celu debugowania, aby upewnić się, że DEBUGjest ustawiony - zrób to, wybierając projekt i klikając kartę ustawień kompilacji. Wyszukaj DEBUGi sprawdź, czy rzeczywiście DEBUGjest ustawiony.

Zwróć jednak uwagę. Możesz zobaczyć DEBUG zmieniony na inną nazwę zmiennej, taką jak DEBUG_MODE.

Karta Ustawienia kompilacji ustawień mojego projektu

następnie warunkowo kod DEBUG w plikach źródłowych

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif
Damo
źródło
Dziękuję za odpowiedź, jeśli spróbuję zrobić w ten sposób: #ifdef DEBUG NSLog@("Something");#else//#endifto nie działa. Jak mogę zainicjować przycisk lub zalogować coś do konsoli, czy możesz edytować swoje pytanie?
Malloc
Co powiesz na Swift?
technofil,
czy mogę zmienić to makro programowo w czasie wykonywania? Chcę włączyć przycisk, który przełącza się na produkcyjne interfejsy API. Na tym przycisku chcę zmienić DEBUG na 0 i wyświetlić komunikat, że użytkownik musi ponownie uruchomić aplikację. Więc następnym razem użyje produkcyjnych interfejsów API.
Hiren Prajapati
130

Aby znaleźć rozwiązanie w Swift, zapoznaj się z tym wątkiem w SO.

Zasadniczo rozwiązanie w Swift wyglądałoby tak:

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

Dodatkowo będziesz musiał ustawić DEBUGsymbol w Swift Compiler - Custom Flagssekcji dla Other Swift Flagsklucza poprzez -D DEBUGwpis. Przykładowy zrzut ekranu:

wprowadź opis zdjęcia tutaj

Jeehut
źródło
1
Gdzie znajdę kompilator Swift - niestandardowe flagi?
confile
2
@confile: Załączam zrzut ekranu, który powinien wyjaśniać, gdzie znaleźć. Mam nadzieję, że to pomoże!
Jeehut,
1
Pamiętaj, że należy to zdefiniować dla konkretnego frameworka / rozszerzenia, które go używa! Więc jeśli masz rozszerzenie klawiatury / dzisiaj, zdefiniuj je tam. Jeśli masz jakieś inne ramy, to samo. Może to być konieczne tylko wtedy, gdy głównym celem jest cel c ...
Warpzit
dzięki, wygląda na to, że Other Swift Flagsklucz się nie pojawi, chyba że wybierzesz Alli combinedpowyżej
Oscar Zhang
Dzięki! Tego mi brakowało. Ustawiłem go dla Clanga, ale nie dla Szybkiego.
bugloaf
90

Apple już zawiera DEBUGflagę w kompilacjach debugowania, więc nie musisz definiować własnej.

Możesz również rozważyć redefiniowanie NSLogoperacji zerowej, gdy nie jest w DEBUGtrybie, w ten sposób twój kod będzie bardziej przenośny i możesz po prostu używać zwykłych NSLoginstrukcji:

//put this in prefix.pch

#ifndef DEBUG
#undef NSLog
#define NSLog(args, ...)
#endif
Nick Lockwood
źródło
33

Większość odpowiedzi mówiło, jak ustawić #ifdef DEBUG, a żadna z nich nie mówi, jak określić kompilację debugowania / wydania.

Moja opinia:

  1. Edytuj schemat -> uruchom -> konfiguracja kompilacji: wybierz debugowanie / wydanie. Może kontrolować symulator i status testowego kodu iPhone'a.

  2. Edytuj schemat -> archiwum -> konfiguracja kompilacji: wybierz debugowanie / wydanie. Może kontrolować aplikację pakietu testowego i status kodu aplikacji App Store. wprowadź opis zdjęcia tutaj

Qun Li
źródło
Przyznana odpowiedź !!! pomaga mi zidentyfikować mój problem. W moim przypadku utrzymałem ten Archivetryb Debugi przesłałem aplikację do sklepu z aplikacjami. Podczas sprawdzania wyniku po pobraniu aplikacji z iTunes po prostu nie działa. Upewnij się więc, że DEBUG/RELEASEdziała tylko po wybraniu odpowiedniego trybu w Build/Run/Archive.
Bhavin_m
13

Swift i Xcode 10+

#if DEBUGprzekaże DOWOLNĄ wersję rozwojową / kompilację ad-hoc, urządzenie lub symulator. Jest to fałsz tylko w przypadku wersji App Store i TestFlight.

Przykład:

#if DEBUG
   print("Not App Store build")
#else
   print("App Store build")
#endif
Kirill Kudaev
źródło
8

Odpowiedź zitao xionga jest bardzo zbliżona do tego, czego używam; Podaję także nazwę pliku (usuwając ścieżkę z PLIKU ).

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

W xcode 7 pod Apple LLVM 7.0 znajduje się pole - przetwarzanie wstępne , które nazywało się „ Makrami preprocesorów nieużywanych we wstępnie skompilowanych ... ”? Umieszczam DEBUG przed Debugowaniem i działa dla mnie, używając poniższego kodu:

#ifdef DEBUG
    NSString* const kURL = @"http://debug.com";
#else
    NSString* const kURL = @"http://release.com";
#endif
Fa.Shapouri
źródło
4

Jeszcze jeden pomysł na wykrycie:

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

dodaj do pliku mostka nagłówka:

#include "DebugMode.h"

stosowanie:

DebugMode.isDebug()

Szybkie pisanie we właściwościach projektu nie jest potrzebne.

Wiaczesław
źródło
1

Nie jestem pewien, czy odpowiedziałem na pytanie, może mógłbyś wypróbować następujący kod:

#ifdef DEBUG
#define DLOG(xx, ...)  NSLog( \
    @"%s(%d): " \
    xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ \  
    )
#else
#define DLOG(xx, ...)  ((void)0)
#endif 
Zitao Xiong
źródło
Czy możesz wyjaśnić dokładnie, co robi ta definicja? Wygląda schludnie, ale nie do końca to rozumiem. X Zwykle wskazuje zarezerwowane makro Apple, podczas gdy PRETTY_FUNCTION wskazuje coś wygenerowane przez użytkownika, więc wynik jest mylący
P i
2
xx to ciąg formatujący, możesz użyć, co chcesz, jeśli jest identyczny z poprzednim ciągiem. Możesz użyć FUNCTION , ale PRETTY_FUNCTION wypisuje nazwy metod Celu C. ten link wyjaśnia to bardzo dobrze.
Zitao Xiong