2013-08-14 21 views
10

Obecnie buduję dwie aplikacje dla mojego projektu, jedną w wydaniu & inną w debugowaniu (jedyną rzeczą, która zmienia się, są profile udostępniania używane do podpisywania i punktów końcowych). Ze względu na niektóre zasady nie powinienem lokalnie tworzyć plików IPA. Używam programu maven do budowania tych dwóch wersji (wydanie & debugowanie), w oparciu o skrypt. Z powodu tych samych zasad, dane wyjściowe powinny zostać całkowicie usunięte z aplikacji (NSLog, printf ...). Jestem świadomy makr preprocesora, ale nie chcę na nich polegać, ponieważ ktoś (bez wiedzy) może je zmienić i zagrozić temu, co chcę osiągnąć. Więc to, co chcę jest:Usuwanie dzienników po zwolnieniu aplikacji iOS

  1. Umieć wylogować co zechcę, gdy używam mojego symulatora lub kiedy uruchomić bezpośrednio na rzeczywistym urządzeniu
  2. Gdy używam maven zbudować moje aplikacje, to upewnij się, NSLogs są rozebrane lub wyłączone.

Maven opiera się na tym, co znajduje się w odległym repozytorium, aby rzeczywiście dokonać kompilacji, więc jeśli nie jest sposobem na wyłączenie tej logi podczas zdalnego repo popełnić, jest to rozwiązanie jak dobrze ..

+1

Więc niech mi to wprost: Chcesz czasie kompilacji zróżnicowanie ścieżek kod bez żadnych narzędzi, które mamy używane do różnicowania w czasie kompilacji od późnych lat 80-tych? Makra preprocesora nie są niebezpiecznymi zależnościami, to jedyny sposób, w jaki będzie to działało bez żadnych kosztów ogólnych. Jeśli martwisz się, że makra zostały zmienione, dlaczego nie "# błędu", gdy są '# ifndef''d. – CodaFi

+0

@CodaFi dla mnie makra preprocesora są idealnie w porządku. Po prostu nie nazywam strzałów, więc muszę podać alternatywę. :) I nie jest to "różnicowanie w czasie kompilacji", wystarczy wyłączyć wyjście. – Peres

+0

Dobra, myślę, że mam rozwiązanie. – CodaFi

Odpowiedz

1

To ciekawy Żądamy, ale jest to wykonalne, jeśli chcesz zaakceptować trochę kosztów związanych z wywołaniem funkcji dla każdego dziennika, który zostanie pominięty. Wewnątrz EtPanKit framework znajduje się niezła funkcja, która sprawdza, czy pliki, które próbują wywoływać funkcję rejestru, pasują do tablicy zdefiniowanych klas w pliku . Oprócz tego, że jest doskonałym filtrem do debugowania, wystarczy zwolnić wszystkie klucze z pliku plist lub określić inny w wersji Release bez żadnych wartości związanych z kluczem LEPLogEnabledFilenames.

W interesie zapobiegania link-rot, oto sama funkcja i związane z makr, które sprawiają, że nieco ładniejsza zadzwonić:

#define LEPLogStack(...) LEPLogInternal(__FILE__, __LINE__, 1, __VA_ARGS__) 
#define LEPLog(...) LEPLogInternal(__FILE__, __LINE__, 0, __VA_ARGS__) 

#import <Foundation/Foundation.h> 
#import <libgen.h> 
#import <time.h> 
#import <sys/time.h> 
#include <execinfo.h> 
#include <pthread.h> 

static NSSet * enabledFilesSet = nil; 
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

void LEPLogInternal(const char * filename, unsigned int line, int dumpStack, NSString * format, ...) 
{ 
    va_list argp; 
    NSString * str; 
    NSAutoreleasePool * pool; 
    char * filenameCopy; 
    char * lastPathComponent; 
    struct timeval tv; 
    struct tm tm_value; 
    //NSDictionary * enabledFilenames; 

    pool = [[NSAutoreleasePool alloc] init]; 

    pthread_mutex_lock(&lock); 
    if (enabledFilesSet == nil) { 
     enabledFilesSet = [[NSSet alloc] initWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:LEPLogEnabledFilenames]]; 
    } 
    pthread_mutex_unlock(&lock); 

    NSString * fn; 
    fn = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:filename length:strlen(filename)]; 
    fn = [fn lastPathComponent]; 
    if (![enabledFilesSet containsObject:fn]) { 
     [pool release]; 
     return; 
    } 

    va_start(argp, format); 
    str = [[NSString alloc] initWithFormat:format arguments:argp]; 
    va_end(argp); 

    NSString * outputFileName = [[NSUserDefaults standardUserDefaults] stringForKey:LEPLogOutputFilename]; 
    static FILE * outputfileStream = NULL; 
    if ((NULL == outputfileStream) && outputFileName) 
    { 
     outputfileStream = fopen([outputFileName UTF8String], "w+"); 
    } 

    if (NULL == outputfileStream) 
     outputfileStream = stderr; 

    gettimeofday(&tv, NULL); 
    localtime_r(&tv.tv_sec, &tm_value); 
    fprintf(outputfileStream, "%04u-%02u-%02u %02u:%02u:%02u.%03u ", tm_value.tm_year + 1900, tm_value.tm_mon + 1, tm_value.tm_mday, tm_value.tm_hour, tm_value.tm_min, tm_value.tm_sec, tv.tv_usec/1000); 
    //fprintf(stderr, "%10s ", [[[NSDate date] description] UTF8String]); 
    fprintf(outputfileStream, "[%s:%u] ", [[[NSProcessInfo processInfo] processName] UTF8String], [[NSProcessInfo processInfo] processIdentifier]); 
    filenameCopy = strdup(filename); 
    lastPathComponent = basename(filenameCopy); 
    fprintf(outputfileStream, "(%s:%u) ", lastPathComponent, line); 
    free(filenameCopy); 
    fprintf(outputfileStream, "%s\n", [str UTF8String]); 
    [str release]; 

    if (dumpStack) { 
     void * frame[128]; 
     int frameCount; 
     int i; 

     frameCount = backtrace(frame, 128); 
     for(i = 0 ; i < frameCount ; i ++) { 
      fprintf(outputfileStream, " %p\n", frame[i]); 
     } 
    } 

    if (outputFileName) 
    { 
     fflush(outputfileStream); 
    } 

    [pool release]; 
} 
1

Rozumiem, że nie chcesz polegać makra pre-procesorowych , ale jest prosty sposób, aby usunąć wszelkie sprawozdania NSLog pomocą pre-procesor:

dodać do nagłówka prefiksu następuje:

#ifndef DEBUG 
#define NSLog(...) 
#endif 

Jeśli DEBUG nie jest def W ten sposób wszystkie instrukcje NSLog zostaną usunięte przez preprocesor w całym kodzie aplikacji. Jeśli DEBUG nie jest dodawany automatycznie w ustawieniach kompilacji, możesz po prostu dodać instrukcję #define DEBUG i skomentować ją, gdy kompilacja zostanie wydana.

To samo można zrobić dla instrukcji printf().

Użyłem tego z powodzeniem w aplikacji, którą wydałem, aby pozbyć się NSLog.

2

To makro spowoduje automatyczne wylogowanie się z trybu zwolnienia. Po prostu wymień wszystkie NSLog na DLog iw przyszłości używaj DLog do logowania. Przykład: DLog(@"Text : %@",sometext);

#ifdef DEBUG 
# define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); 
#else 
# define DLog(...) 
#endif 
+0

Jestem świadomy makr preprocesora, ale nie chcę na nich polegać ... – Peres

0

Możesz dodać kompletny system dziennika tak:

#ifndef Logs_h 
#define Logs_h 

    /* Log levels */ 
    #define LOG_LEVEL_NO_LOG 0 
    #define LOG_LEVEL_ONLY_ERRORS 1 
    #define LOG_LEVEL_ERROS_AND_WARNINGS 2 
    #define LOG_LEVEL_LOG_ALL 3 
    /* Log levels */ 


    #ifdef DEBUG 
     #define LOG_LEVEL LOG_LEVEL_LOG_ALL /* <-- Change The Log Level here */ 
    #else 
     #define LOG_LEVEL LOG_LEVEL_NO_LOG /* No logs on release now */ 
    #endif 


    /* Logs Macros */ 

    #if LOG_LEVEL >= LOG_LEVEL_LOG_ALL 
     #define DebugLog(fmt, ...) NSLog(@"[Debug] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__) 
    #else 
     #define DebugLog(...) /* */ 
    #endif 

    #if LOG_LEVEL >= LOG_LEVEL_ERROS_AND_WARNINGS 
     #define WarnLog(fmt, ...) NSLog(@"[Warning] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__) 
    #else 
     #define WarnLog(...) /* */ 
    #endif 

    #if LOG_LEVEL >= LOG_LEVEL_ONLY_ERRORS 
     #define ErrorLog(fmt, ...) NSLog(@"[Error] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__) 
    #else 
     #define ErrorLog(...) /* */ 
    #endif 

#endif