Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use asl.h in swift-ios files

Tags:

logging

ios

swift

I am new to ios/swift. I would like to use logging c-functions from asl.h in swift files. Anyone? I googled and people seem to write their own logging swift classes. No disrespect, but I would like to use just asl. That is, swift does not like #include <asl.h> and it does not like me just calling asl_log(NULL, NULL, ASL_LEVEL_INFO, "Hello World!");

like image 452
Dmitry Konovalov Avatar asked Nov 01 '14 00:11

Dmitry Konovalov


3 Answers

Thanks, and with the help from http://doing-it-wrong.mikeweller.com/2012/07/youre-doing-it-wrong-1-nslogdebug-ios.html I made the following modifications:

Added a BRASL.h file to the project with the following contents:

//
//  BRASL.h
//

#ifndef BRASL_h
#define BRASL_h

#import <asl.h>
#import <Foundation/Foundation.h>


// Define which loglevel is necessary for deployment and development
// =================================================================
// Used to conditionally implement the log functions. All log
// functions are defined so the compiler does not complain. But only
// those logfunctions that are used will contain code.
// =================================================================
#ifndef BRASL_LOG_LEVEL
    // DEBUG is set in the project build-settings
    #if DEBUG == 1
        // Set logging level for development
        #define BRASL_LOG_LEVEL ASL_LEVEL_DEBUG
    #else
        // Set logging level for deployment
        #define BRASL_LOG_LEVEL ASL_LEVEL_NOTICE
    #endif
#endif


// Define the log functions
// ========================
void aslEmergency(NSString *string);
void aslAlert(NSString *string);
void aslCritical(NSString *string);
void aslError(NSString *string);
void aslWarning(NSString *string);
void aslNotice(NSString *string);
void aslInfo(NSString *string);
void aslDebug(NSString *string);


#endif

Then added the corresponding .m file with:

//
//  BRASL.h
//

#import "BRASL.h"


// We need this to set asl up to also write the information to the debugger
// ========================================================================
static void AddStderrOnce() {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        asl_add_log_file(NULL, STDERR_FILENO);
    });
}


// Implement the log functions where necessary
// ===========================================
#if BRASL_LOG_LEVEL >= ASL_LEVEL_EMERG
void aslEmergency(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_EMERG, "%s", [string UTF8String]);
}
#else
void aslEmergency(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_ALERT
void aslAlert(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_ALERT, "%s", [string UTF8String]);
}
#else
void aslAlert(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_CRIT
void aslCritical(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_CRIT, "%s", [string UTF8String]);
}
#else
void aslCritical(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_ERR
void aslError(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", [string UTF8String]);
}
#else
void aslError(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_WARNING
void aslWarning(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_WARNING, "%s", [string UTF8String]);
}
#else
void aslWarning(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_NOTICE
void aslNotice(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "%s", [string UTF8String]);
}
#else
void aslNotice(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_INFO
void aslInfo(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_INFO, "%s", [string UTF8String]);
}
#else
void aslInfo(NSString *string) {}
#endif

#if BRASL_LOG_LEVEL >= ASL_LEVEL_DEBUG
void aslDebug(NSString *string) {
    AddStderrOnce();
    asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%s", [string UTF8String]);
}
#else
void aslDebug(NSString *string) {}
#endif

And of course the bridging file

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "BRASL.h"

Then in my swift code I can use for example:

aslInfo("Initializing managed object context")

So far so good, seems to work as advertised :)

like image 122
Rien Avatar answered Nov 15 '22 05:11

Rien


So far, the easiest way I found is the following (it works for any c-libraries):

Step-1: File-New-File Objective-C, e.g. MyBridgeToACLib.h, MyBridgeToACLib.m

Step-2: In MyBridgeToACLib.h

#import <Foundation/Foundation.h>
@interface MyBridgeToACLib : NSObject    
  // here you need to declare a function for each c-function you want to call from swift, e.g. : 
  + (void) debug:(NSString*) nsStr;
  + (void) debug:(NSString*) nsStr secondValue:(NSInteger) nsInt;
@end

Step-3: In MyBridgeToACLib.m

#include <asl.h>  // or any c-library you need to call from Swift
#import "MyBridgeToACLib.h"

@implementation MyBridgeToACLib

+ (void) debug:(NSString*) nsStr {
  // here you need to convert from Objective-C types to C-types, e.g. NSString to char*
  const char *cStr = [nsStr UTF8String];
  printf("%s\n", cStr);
  // call your c-functions
  asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%s", cStr);
}

+ (void) debug:(NSString*) nsStr secondValue:(NSInteger) nsInt {
  const char *cStr = [nsStr UTF8String];
  long cInt = nsInt;
  printf("%s%li\n", cStr, cInt);
  asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%s%li", cStr, cInt);
}
@end

Step-4: Setup the following "MyProjectName-Bridging-Header.h". Google "XCode Bridging-Header" for instructions.

    // Swift and Objective-C in the Same Project   
//https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html
    //
    // Here import all of your "Bridge"-headers 
    #import "MyBridgeToACLib.h"
like image 25
Dmitry Konovalov Avatar answered Nov 15 '22 04:11

Dmitry Konovalov


Here are a few open-source projects that might be of interest to you:

• CleanroomASL — A low-level-but-Swiftified API for reading from & writing to the Apple System Log

• CleanroomLogger — A high-level Swift logging API that supports writing to the ASL

• AppleSystemLogSwiftPackage — A Swift Package Manager (SPM) declaration that allows you to 'import ASL' from within your code. (Note that SPM only builds for Mac OS X at the moment, so it won't help you with iOS for now.)

Based on what you've written, I suspect the CleanroomLogger project would be the most appropriate for your use.

Hope you find this helpful,

E.

Full disclosure: I've contributed to each of these projects.

like image 39
emaloney Avatar answered Nov 15 '22 04:11

emaloney