Swift CoreMIDI Callbacks

The following was tested with Swift 2.1.1.  I am far from a Swift expert.  I do use “;” and “()” in Swift sometimes even though not necessary.  This is because I develop in many languages and the code flows from my fingers this way.

Suppose you have a Cocoa app with a ViewController and you want to update the UI when a MIDI source or destination is added or removed, or a MIDI packet is received. There are a few snags along the way that you may encounter. CoreMIDI provides references for the application to pass in that can be used in the callbacks. But converting between Swift and C structs may not be intuitively obvious. Another difficulty is casting MIDINotification to MIDIObjectAddRemoveNotification. If this isn’t done properly the bits will get converted but the actual data in the MIDIObjectAddRemoveNotification struct will be trash. This is how I handled callbacks in Swift.

First I created a protocol that my ViewController implemented so that casting would be a little cleaner.

Then I implemented the callbacks as global Swift functions. The bridgeMutable() and unbridgeMutable() utility functions were based on information I found on stackoverflow.com

Finally the view controller was implemented using the following code snippets. Note that another utility function invokeLater is used so that the UI can be updated off of the high priority CoreMIDI event thread.

Swift CoreMIDI without Objective-C (Updated for Swift 3)

Update: Code has been added for Swift 3 and XCode 8

These examples do little to no error checking and it is assumed your system has at least one source and one destination. Run them in a macOS Playground.

List the MIDI sources and destinations (Swift 3)

 

List the MIDI sources and destinations (Swift 2)

 

Create a client, connect a destination, and play a note (Swift 3)

 

Create a client, connect a destination, and play a note (Swift 2)

 

Connect an input source and receive data via a callback (Swift 3)

 

Connect an input source and receive data via a callback (Swift 2)