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!");
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 :)
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"
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With