Calling NSLog from C in Swift App
I have had to write part of a Swift app dealing with CoreAudio for OSX in C because I couldn’t get it to work in Swift. There is a function NSLog in Foundation which would be nice to use from C for logging errors etc.
However if you put
#include <Foundation/Foundation.h>
in your header file it triggers a multitude of errors due the Objective C function definitions. The definition of NSLog in the docs is
void NSLog(NSString *format, ...);
The docs entry for NSString says:
NSString is “toll-free bridged” with its Core Foundation counterpart, CFStringRef. See “Toll-Free Bridging” for more information.
So I tried putting an entry in the C include file:
void NSLog(CFStringRef format, ...);
But because the include files are also read by the Swift compiler this also generated errors due to multiple definitions of the function. So I tried putting the definition in the C source file. This also requires an entry in the C include file for CFStringRef.
#include <CoreFoundation/CoreFoundation.h>
This didn’t cause any conflicts and worked nicely.
#include "Audio.h"
void NSLog(CFStringRef format, ...);
// ...
// Open it
OSStatus status = AudioComponentInstanceNew(cp, &audio.output);
if (status != noErr)
{
// AudioComponentInstanceNew
NSLog(CFSTR("Error in AudioComponentInstanceNew %s (%d)"),
AudioUnitErrString(status), status);
return status;
}
Having got that to work, I updated the function I originally wrote in Swift to return a CFStringRef and put it’s definition in the include file.
CFStringRef AudioUnitErrString(OSStatus status);
It can then be called from Swift:
func DisplayAlert(_ status: OSStatus, _ message: String,
_ informativeText: String)
{
let alert = NSAlert()
alert.alertStyle = .warning
alert.messageText = message
let error = (status > 0) ? UTCreateStringForOSType(OSType(status))
.takeRetainedValue() as String :
AudioUnitErrString(status).takeRetainedValue() as String
alert.informativeText = informativeText + ": " + error +
" (" + String(status) + ")"
alert.runModal()
}
Which also worked.