Xcode / iOS: как определить, выполняется ли код в сборке DEBUG / RELEASE?

241

Я делаю приложение, которое обрабатывает конфиденциальные данные кредитной карты.

Если мой код работает в режиме отладки, я хочу записать эти данные в консоль и сделать несколько дампов файлов.

Однако в окончательной версии магазина приложений (то есть, когда он работает в режиме выпуска) важно, чтобы все это было отключено (угроза безопасности)!

Я постараюсь ответить на мой вопрос как можно лучше; поэтому возникает вопрос: «Является ли этот путь решения правильным или лучшим способом сделать это?»

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

#if( IS_DEBUG )  
#define MYLog(args...) NSLog(args)  
#else  
#define MYLog(args...)  
#endif  
Число Пи
источник

Ответы:

248

Проверьте параметры сборки вашего проекта в «Apple LLVM - Preprocessing», «Macro Preprocessor» для отладки, чтобы убедиться, что DEBUGона установлена ​​- сделайте это, выбрав проект и нажав на вкладку «Параметры сборки». Найдите DEBUGи посмотрите, действительно ли DEBUGэто задано.

Обратите внимание, хотя. Вы можете увидеть, что DEBUG изменено на другое имя переменной, например DEBUG_MODE.

Вкладка «Настройки сборки» настроек моего проекта

тогда условно код для DEBUG в ваших исходных файлах

#ifdef DEBUG

// Something to log your sensitive data here

#else

// 

#endif
Дамо
источник
Спасибо за ваш ответ, если я попытаюсь сделать так: #ifdef DEBUG NSLog@("Something");#else//#endifэто не работает. Как я могу инициализировать кнопку или записать что-то на консоль, пожалуйста, вы можете отредактировать свой вопрос?
Маллок
Как насчет Свифта?
технофил
я могу изменить этот макрос программно во время выполнения? Я хочу включить кнопку, которая переключается на производственные API. На этой кнопке я хочу изменить DEBUG на 0 и отобразить сообщение, необходимое пользователю для перезапуска приложения. Поэтому в следующий раз он будет использовать производственные API.
Хирен Праджапати
130

Для решения в Swift, пожалуйста, обратитесь к этой теме на SO.

В основном решение в Swift будет выглядеть так:

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

Кроме того, вам необходимо установить DEBUGсимвол в Swift Compiler - Custom Flagsразделе для Other Swift Flagsключа через -D DEBUGзапись. Смотрите следующий скриншот для примера:

введите описание изображения здесь

Jeehut
источник
1
Где я могу найти Swift Compiler - Custom Flags?
конфил
2
@confile: я приложил скриншот, который должен прояснить, где найти. Надеюсь, поможет!
Jeehut
1
Помните, что это должно быть определено для конкретной платформы / расширения, которое его использует! Так что, если у вас есть расширение клавиатуры / сегодня, определите его там. Если у вас есть другой вид фреймворка, то же самое. Это может быть необходимо, только если основной целью является цель c ...
Warpzit 21.10.16
спасибо, кажется, Other Swift Flagsключ не появится, если вы не выберете Allи combinedвыше
Оскар Чжан
Спасибо! Это то, чего мне не хватало. Я сделал это для Clang, но не для Swift.
bugloaf
90

Apple уже включает DEBUGфлаг в отладочные сборки, поэтому вам не нужно определять свой собственный.

Возможно, вы также захотите просто переопределить NSLogнулевую операцию, когда не в DEBUGрежиме, так ваш код будет более переносимым, и вы можете просто использовать регулярные NSLogоператоры:

//put this in prefix.pch

#ifndef DEBUG
#undef NSLog
#define NSLog(args, ...)
#endif
Ник Локвуд
источник
33

В большинстве ответов говорилось о том, как установить #ifdef DEBUG, и ни в одном из них не говорилось, как определить сборку отладки / выпуска.

Мое мнение:

  1. Изменить схему -> запустить -> построить конфигурацию: выбрать отладку / выпуск. Он может управлять симулятором и статусом кода вашего тестового iPhone.

  2. Редактировать схему -> Архив -> Конфигурация сборки: выбрать отладку / выпуск. Он может контролировать тестовый пакет приложения и статус кода приложения App Store. введите описание изображения здесь

Кун Ли
источник
Награжденный ответ !!! это помогает мне определить мою проблему. В моем случае я сохранил Archiveрежим Debugи отправил приложение в магазин приложений. При проверке результата после загрузки приложения из iTunes оно просто не работает. Поэтому убедитесь, что DEBUG/RELEASEработает только при выборе соответствующего режима в Build/Run/Archive.
Bhavin_m
13

Swift и Xcode 10+

#if DEBUGперейдет в ЛЮБУЮ разработку / специальную сборку, устройство или симулятор. Это ложно только для сборок App Store и TestFlight.

Пример:

#if DEBUG
   print("Not App Store build")
#else
   print("App Store build")
#endif
Кирилл Кудаев
источник
8

ответ Зитао Сюн очень близок к тому, что я использую; Я также включать в себя имя файла (отгонка пути FILE ).

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

В xcode 7 в Apple LLVM 7.0 есть поле - предварительная обработка , которое называется « Макросы препроцессоров, не используемые в скомпилированных ... »? Я поставил DEBUG перед Debug, и он работает для меня, используя следующий код:

#ifdef DEBUG
    NSString* const kURL = @"http://debug.com";
#else
    NSString* const kURL = @"http://release.com";
#endif
Fa.Shapouri
источник
4

Еще одна идея, чтобы обнаружить:

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

добавить в заголовочный файл моста:

#include "DebugMode.h"

использование:

DebugMode.isDebug()

Не нужно что-то писать в свойствах проекта swift flags.

Вячеслав
источник
1

Не уверен, если я отвечу на ваш вопрос, может быть, вы могли бы попробовать этот код:

#ifdef DEBUG
#define DLOG(xx, ...)  NSLog( \
    @"%s(%d): " \
    xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ \  
    )
#else
#define DLOG(xx, ...)  ((void)0)
#endif 
Ситао Сюн
источник
Не могли бы вы уточнить, что именно делает это определение? Это выглядит аккуратно, но я не совсем понимаю. X Обычно обозначает зарезервированный макрос Apple, тогда как PRETTY_FUNCTION указывает на то, что пользователь сгенерировал, поэтому результат сбивает с толку
P i
2
xx - строка формата, вы можете использовать все, что захотите, если она идентична предыдущей строке. Вы можете использовать FUNCTION , но PRETTY_FUNCTION выводит имена методов Objective-C. эта ссылка объясняет это очень хорошо.
Зитао Сюн