I'm going to implement an observer to be notified when a specific volume disappeared.
The notifications in NSWorkspace
are not an option, because I need a notification about device switched off rather than device unmounted.
Registering is pretty easy ( I left out the error handling)
var callbackSession : DASession?
let callbackSession = DASessionCreate(kCFAllocatorDefault)
DASessionSetDispatchQueue(callbackSession!, DispatchQueue.global())
DARegisterDiskDisappearedCallback(callbackSession!, nil, volumeDidDisappearCallback, nil)
The callback closure is
let volumeDidDisappearCallback : DADiskDisappearedCallback = { (disk, context) in
// do something with disk
}
The unregister method
func DAUnregisterCallback(_ session: DASession, _ callback: UnsafeMutableRawPointer, _ context: UnsafeMutableRawPointer?)
expects an generic UnsafeMutableRawPointer
rather than one of the specific callback types.
When I pass the callback closure to the callback
parameter I get
Cannot convert value of type 'DADiskDisappearedCallback' (aka '@convention(c) (DADisk, Optional) -> ()') to expected argument type 'UnsafeMutableRawPointer'
My question is: How can I convert the callback object volumeDidDisappearCallback
to UnsafeMutableRawPointer
?
DADiskDisappearedCallback
is defined as
public typealias DADiskDisappearedCallback = @convention(c) (DADisk, UnsafeMutableRawPointer?) -> Swift.Void
which is the Swift mapping of the C function pointer
typedef void (*DADiskAppearedCallback)(DADiskRef disk, void *context);
The unregister function is defined in C as
void DAUnregisterCallback(DASessionRef session, void *callback, void *context);
with a void *callback
parameter, and in C you can pass the various
kinds of callback function pointers (DADiskAppearedCallback
, DADiskDescriptionChangedCallback
, ...) without casting.
In Swift you have to cast the function pointer to a void pointer explicitly:
let cb = unsafeBitCast(volumeDidDisappearCallback, to: UnsafeMutableRawPointer.self)
DAUnregisterCallback(callbackSession!, cb, nil)