Multiselect UITableView with limited selections

Swift Language

Multiselect UITableView with limited selections

Simple example of creating a multi-select UITableView, but allow only a limited number of selected cells.


Table of Contents

I wanted a multi-select table view but limit the number of selected cells. The “answers” on StackOverflow were quite awful – which is true > 50% of the time.

So here is a simple working example

How to

Table of Contents

Add a table view to your storyboard. (I know, well duh). In the attributes editor choose multi select.
Set your viewcontroller to be the table datasource and delegate. You know, the usual.

In your view controller, do the usual datasource setup.

For the limiting functionality, you need to do this in the delegate.

In my viewcontroller, I added a variable – the limit. Then in the delegate’s willSelectRowAtIndexPath func I compared the current number of selected cells (tableView.indexPathsForSelectedRows) to the limit returning nil if it’s over the limit.

That’s it. None of the contortions you see on SO.

In the other delegate methods, I just add eye candy.

Limited TableView Selection

And when you go over the limit.

Limited TableView Selection Alert


Table of Contents

All you really need to do is done in the delegate’s willSelectRowAtIndexPath func.


Table of Contents

Posted in Swift | Leave a comment

tvOS Framework Target bug


There be bugs here

Getting past the simple project stage with your tvOS app?

Maybe you’re putting reusable/common code in frameworks and then linking to them from your tv project.

What could go wrong?



Table of Contents

So I created an Xcode workspace. Then under Framework & Library, I created and added a TV Framework project. I created a class in the framework then built it.

Then I created a TV app. In this project I set “Linked Frameworks and Libraries” to use my framework. I also added the framework to “Embedded Binaries”. If you don’t do this, you will get a link failure when you run on the actual device.


In the app I imported the framework and referenced the (public of course) framework class.

It works!


Here’s the Project Navigator. Total grooviosity.


The Problem


Table of Contents

So, what am I complaining about?

I have another pile of code that works on iOS and Cocoa. In this project (a “Cocoa Touch Framework”, I simply have two targets – one for iOS and Cocoa. In the code I use #if os(iOS) or os(OSX). You can check to tvOS too.

Like this:

I’m sure you’ve done that too. That works just fine.

So, what’s the problem?

I’m getting there.

In your multi-target project, add a TV framework target. If it works for Cocoa and iOS, it should work for tvOS too, right?

Well, sort of. It works in the simulator but not on the device.

Here is the same setup as above in the app.

This is what the Project Navigator looks like:


Lots of red.

Let’s see what we get when you select the framework in the app.


That’s not where it should be. If you look at the other framework, it’s in the Derived Data directory. Actually, that’s where it is (i.e. when I look in the derived data directory, it’s there), but Xcode thinks it’s in the project directory. (btw., the Embedded Binaries section shows the same wrong path)

Would you know how to fix this?



Table of Contents

TV framework targets added to a project don’t link correctly in your app when run on the device.



Table of Contents


Posted in tvOS | Leave a comment

tvOS: playing audio


Playing MIDI on tvOS

According to Apple’s App Programming Guide for tvOS, AVFoundation is supported in tvOS.


Let’s use AVMIDIPlayer to play a file!

Set up

Table of Contents

AVMIDIPlayer’s init func wants two URLs: one to a MIDI file and another to a SoundFont or DLS file.

I created a standard MIDI file in Sibelius. The SoundFont I used is the one distributed with MusesCore.

Here is how I created the player.

And then I played it by calling the cunningly named play() function. I use a completion handler to reset the playback position.

This is pretty much what I do in iOS and Cocoa and it works.

The result

Table of Contents

In the tvOS simulator, it works almost OK. You hear sine waves – just like in iOS. When you run it on an actual device, you should hear the instruments.

In tvOS, not so much. I hear two notes with a loaded instrument, and then blammo.

Removing the dispatch_async call yields the same result.

Here is the love letter from the debugger.

By the way, I also tried MusicPlayer and Core Audio since the guide says AudioToolbox and AudioUnit are supported too. Same result. The stack trace shows that error occurs deep in the bowels of AudioToolbox.


Table of Contents

Well, crap. It would be nice to be able to play MIDI files; I’d like to port my ear training app to tvOS. But without playback, it would be reaaalllly hard to recognize and identify the intervals, chords, and scales playing.


Table of Contents

I spent far too much time on this. I looked at my code over and over again. I was certain that I was doing it correctly (but there is always that doubt every developer deals with), so why was it crashing?

It wasn’t my code.

It was the MusesScore sound font. Out of desperation, I tried another sound font and the sun started shining , the birds sang, and my cat’s litter box was magically clean. Oh, and it played on the AppleTV.


Table of Contents

App Programming Guide for tvOS


MusesCore SoundFont page

Github project

If you need a cable to connect your MacBook to your AppleTV, I bought this one.

Posted in MIDI, tvOS | Tagged , | 2 Responses

Apple TV tvOS hello world app in Swift

Swift Language

Apple TV TVML tvOS hello world app in Swift


Table of Contents
So, you saw the shiny new AppleTV demo on the Apple Live Event. Finally we can write apps for the beast! Like most of you, I downloaded the Xcode 7.1 beta to jump in. Hey, there’s a project template! Let’s try that. Oh, that’s it? Looks like any other iOS app. Where’ the TV code? Sigh. I guess I’ll have to RTFM.

There are two types of app. One relies on “templates” written in XML called TVML (Television markup language). The other “low level” way is to write custom apps in Swift (or objc). Here is a list of iOS APIs that did or did not make it to tvOS. (Interesting that AudioToolbox made it but CoreMIDI didn’t – and no mention of Core Audio). In this post, I’ll talk about the TVML approach.

Apple has provided us with their usual almost-adequate tvOS documentation. After you get an idea of how it works, you get a “hello world” type page named Creating a Client-Server App.

Cool. The sample code is not downloadable, so you need to scrape the code off the page and fix the problems.
Not cool.

Here’s my attempt at being a bit more helpful.

Getting started

Table of Contents

Go ahead and read Creating a Client-Server App. This will give you a good conceptual overview. I’ll give you action items below.


Table of Contents

Let’s start with the server side. For development, you will need to serve JavaScript and TV Markup (TVML) files. There are various ways to do this. You can use Python, but I don’t like snakes or syntactic whitespace (both will bite you). Since you’re hip and happenin’ you probably have Node.js installed. So, let’s bask in your grooviosity and use Node to serve your files.

You will need to install http-server via npm.


Then to serve the files in a subdirectory named “public” you simply type

Or if your files are in a different directory

So, what’s in that directory?

Go ahead and create a tvOS “Single View Application” project. Now drop to a terminal and create a directory named public under your project. Then import that directory to your project. Wouldn’t it be nice if you could do this directly in Xcode?

Now, you need two files (to start) in this directory. First, the JavaScript. I created a file named tv.js. Name it what you’d like. Here is Apple’s code:

Don’t bother copying it, I’ll point you to a Github repo later.

The other file you need is a TVML file. Note that in the onLaunch function I referenced a file named yo.tvml. Go ahead and create it in the public directory.

This is Apple’s minimal example. In my next blog post, I’ll go into more details, but if you want more now, read about Templates.

In the terminal, start the http-server. In another terminal (or tab if you use iTerm) you can test it with curl. Or use your browser.

Yay. You’re serving if you see the file’s contents.


Table of Contents

Make these modifications to your app delegate. This is how your app finds the JavaScript you’re serving. If you named your JavaScript file differently, modify the name here.

That’s it for your Swift code.


Table of Contents

If you run your app now, it will crash with a security problem. Apple says read the
App Transport Security Technote.

Here’s the tl;dr.

Open your Info.plist as source code and add this key.

While you’re in Info.plist, delete the storyboard reference. You won’t be using a storyboard. You can delete the ViewController.swift file too (as specified in Apple’s documentation).

Run it now.

That complicated TVML file we served looks like this:

hello tvOS



Table of Contents

tvOS TVML apps use a client-server architecture. You need to serve a JavaScript file and TVML files from a web server. Your Swift code will reference this JavaScript file. Most of your UI will be written in TVML.


Table of Contents

Since I wrote this, Apple has published some sample code that you can download as a project. Yay.

Here is their TVML example. As usual it’s a dog’s dinner rather than a tutorial.


Table of Contents

Posted in Apple, Swift, tvOS | 2 Responses

Swift NSTableView and NSArrayController

Swift Language

Swift NSTableView and NSArrayController

In my NSTableView column chooser example, I used a table data source and delegate to manage the table’s data. Just like iOS. Cocoa offers other options. In this example, I’ll look at “binding” to an NSArrayController.


Table of Contents

The Cocoa Bindings system allows us to write less code at the expense of doing more configuration in IB. Instead of writing a data source and delegate for our table, we are going to “bind” to an NSArrayController and have the array controller manage the data.

Data model

Table of Contents

You can’t use Swift structs with Cocoa Bindings.

The Cocoa Bindings system uses Key-Value Observing (KVO). KVO works by intercepting the field access messages sent to the observed object. That means we need to write a KVO friendly Swift class.

So, my Person struct from the previous post is now a class that inherits from NSObject.

In the ViewController, I create an array that holds some example data.

Nothing unusual here, except for the dynamic modifier on the array variable. We are going to create an NSArrayController that will bind to this array via KVO. With the dynamic modifier, the messages sent to the array can be intercepted by the system. As a side note, you’d think that you would also need to mark the Person instance variables as dynamic also. It seems to work without doing so. I’ve included unit tests in the Github project verifying this – as well as the complete project which verifies this.

Array Controller

Table of Contents

Now, in IB, find the Array Controller (it will be green) in the Object Library (^⌥⌘3) and drag one to your View Controller Scene. Select the array controller and open the Identity Inspector (⌥⌘3). Under Document, set the Label to “Person Array Controller”. You don’t have to do this, but it makes it less confusing.

Open the Assistant Editor (⌥⌘⏎) and select ViewController if it’s not shown. Now create an outlet for the array controller in the ViewController (control-drag).

Select your array controller in IB. Open the Attributes Inspector tab (⌥⌘4). Under Object Controller set the mode to class and the class name to TableBinding.Person. You need to fully qualify the Person class name with the project name (actually target/module name) which in my case is TableBinding. Swift sort-of-has implicit namespaces. This will allow the array controller to create new instances of your Person class.

Table View

Table of Contents

Drag a Table View from the object library (^⌥⌘3) onto your ViewController and size it. We’re going to add a few buttons at the bottom, so leave a bit of space there.

Now choose your Table view in the outline (to be sure). It is in the ViewController under the Bordered ScrollView and Clip View. In the Attributes Inspector (⌥⌘4), set the number of columns to 3 (one for each of the fields in Person). Open the Bindings Inspector (⌥⌘7).

There are two bindings we need to create for the table: the table’s content and selection indexes to the array controller.

Open up Table Content. Check the Bind To checkbox and select your array controller (you should see the name you set, “Person Array Controller”, in the Identity Inspector) from the option menu. The field that says Controller Key should be arrangedObjects, which is a field in the array controller. There is no Model Key Path to set. You might get a red checkmark, but it seems to be ok.

Scroll down a bit, open up Selection Indexes, and do the same: hit the checkbox, then select the array controller. The Controller key is selectionIndexes.

Binding the Columns

Table of Contents

Now we need to bind each column to a field in the Person class.

In the outline, open up the table view and you will see 3 columns. Select the first one, open up the Attributes Inspector, and set the title to Given Name. You can also choose a title font here if you’d like. Make certain the state is “editable”. Now do the same to the other columns and give them appropriate names (familyName and age).

Now to set the binding. Open up the first table column, “Given Name”. You will see a TableCellView. Open that up too. You will then see an item confusingly called “Table View Cell”. It’s actually an NSTextField. (you can change the title in the Attributes Inspector if you’d like).

This is the hierarchy:
NSTableColumn -> NSTableCellView -> NSTextField
(the titles are: Given name -> Table Cell View -> Table View Cell)

You want to set the binding on the NSTextField.

Select the text field, and open the Bindings Inspector (⌥⌘7). Press the “Bind To” check box then select “Table Cell View” from the option menu. Set the Model Key Path to objectValue.givenName. (givenName is the Person field to which you’re binding the text field)

Do the same for the other columns, with the appropriate Person field name.

Go ahead and run the project. You should see the data in your table.

Adding/Removing rows

Table of Contents

Now drag Push Buttons to your view controller to add and remove a row, and another to print the array to the console for debugging. Create actions in the ViewController for each.

Note that I’m using the arrayController outlet to modify the data and not the array directly.

This will work, but one of the points of the array controller is to minimize code. Go ahead and comment out the add/remove actions. Control drag from the add button to the array controller now. You should see an action pop up that will include an add method (and a remove method too, so do that next for the other button).

One thing I haven’t found, is a hook or callback after these methods are invoked. In my hand written addPerson func, I scrolled the table to show the new Person. I don’t know how to do that with the array controller binding.
Do You?

Run the project, then add and remove rows.
Cool huh?

Click on a new Person to change the values. You can’t – even though you set the editable attribute on the table columns.

Select each of the column text fields (command click for multiple selection).
Open the Attributes Inspector. Find the option menu that says Behavior. Choose Editable.
That’s it. Run it again, add a row, and you should be able to change the values.


Table of Contents

Cocoa Bindings are available for most UI controls. We looked at just the NSTableView and NSArrayController here. What this bought us was less code but more IB configuration. And as you see, you have to set exactly the right things on multiple items. Better than code? What do you think?


Table of Contents

Posted in Cocoa, Swift | Tagged , | 3 Responses

Swift NSTable Column Chooser

Swift Language

Swift NSTable Column Chooser

Although I wrote NeXTStep programs back in the 1980s for my dissertation, I haven’t written many Cocoa programs. The extra Apple Developer fee for OSX apps was something I didn’t want to pay in addition to the iOS fee. OK, I’m cheap. But how many bags of cat food would that $99 buy?

At WWDC15, Apple dropped the additional $99 fee. So, I’m guessing that there are some iOS developers out there adding Cocoa to their bag of trix. This is aimed at iOS developers, so if you’re a beginning beginner, some things might be vague. Sorry.


Table of Contents

If you’re familiar with the UITable class and its minions, the NSTable should be fairly easy for you. We will make a Cocoa Application project with a storyboard, add an NSTable to the storyboard, and then write the code.

Project setup

Table of Contents

Create a new Cocoa Application project. Open the storyboard, and drag a Table View to the ViewController. This is pretty much like what you do in iOS. The storyboard will put the table view inside a scroll view automatically. Select the table view and the attributes inspector. Set the number of columns to 3 (our struct has 3 fields). Note that the “content mode” is set by default to “View Based”. More on that in a bit.

Optional: one time saver is the “autosave” option a bit lower down on the attribute inspector. Simply check the box and make up a user defaults name and it will remember the user’s preference for column size and order.

For each column in the table, you need to set the identifier in the identity inspector (⌥–⌘-3) and title in the attributes inspector (⌥–⌘-4). The identifiers I use are the names of the fields in the data struct so I don’t confuse myself.

NSTable setup

Table of Contents

I’m going to make the ViewController a table data source and delegate. So it will needs some data. Here’s a simple struct with some data (more in the github example).

Table data

Now, the table protocols. The NSTableViewDataSource will return the data. Sort of. There are a few ways to configure an NSTableView : “Cell Based” and “View Based”. The latter seems to be more flexible and it’s the default setting, so I’ll use that. If you opt for “Cell Based”, then the NSTableViewDataSource will need the objectValueForTableColumn function.

For our View Based table, the delegate will return the data via viewForTableColumn.
We didn’t change anything in the storybaord configuration for the table cells. We just said we wanted 3 of something. That something for a View Based table is an NSTableCellView. You create a reusable cell view via tableView.makeViewWithIdentifier. The I retrieve the appropriate data from the array, and set each view’s text field to that data by looked at the column identifier.

Control-Drag from the table to the view controller (twice) to set the data source and delegate.

At this point, your table should work.

Run the project and see what happens.

Context Menu

Table of Contents

To make the column selection work, I will create a context menu and attach it to the header of the table. I call this from viewDidLoad.

Let’s create the context menu first.

So, I create an NSMenu then iterate over the table columns and create an NSMenuItem via addItemWithTitle. Each item will have its action set to the contextMenuSelected function I’ll talk about next. I check the user defaults to see if a column identified by its identifiers is hidden or not and then set the state appropriately. I show how to save the defaults later.

The action for each NSMenuItem toggles the value of the column’s hidden property and also the state of the menu item to match. If you’ve hidden a column, there is screen real estate that needs to be dealt with. There are two things you can do. Tell the table view to siteToFit or size just the last column. I don’t know which one I like better. Try them both and see what you like.

Finally, the state of the column’s hidden property needs to be save in user defaults. So I call a func to do that. Let’s look at that next.

To save the value of the hidden property of each table column, I create a Dictionary with the column identifier as the key and the hidden property as the value. Then I just save the Dictionary in user defaults. Easy.

Before I knew about the auto column save feature I mentioned, I saved a Dictionary of Dictionaries to save multiple column properties. The auto feature saves some code.

In the AppDelegate, you need to register the user defaults. In real life I’d use a plist. Here I’m just hard coding it.

You can check the user defaults in the Terminal. Use the bundle identifier. I set mine to com.rockhoppertech.TableColumnChooser. Look at the General tab of your project to find yours.

What you should see are the non-default values for the user defaults. If you haven’t hidden any columns, you will see only the column autosave values here. Go ahead, hide a column and come back to check.


Table of Contents

It really isn’t hard to create a usable NSTableView and off the user the option of hiding certain columns. You just need to install a context NSMenu and set the hidden property of the NSColumn, then save the values in user defaults.

You can bind a special controller to the table view for it to receive its data. I’ll talk about “Cocoa Bindings” next time.


Table of Contents

Posted in Cocoa, Swift | Tagged | 1 Response

iOS: trimming audio files with Swift

Swift Language

iOS: trimming audio files

I’ve written about how to record audio on iOS using Swift.
But, how do you trim the recording?


Table of Contents

One way to trim an audio file is to use AVFoundation’s AVAssetExportSession. You create an export session instance, set its parameters, and then tell it to export the asset (your audio file) according to those parameters.

In the recorder project, I saved the URL of the recording in the soundFileURL instance variable. To use AVAssetExportSession we need to create an AVAsset from it. Here is a simple action that creates the asset and then call the export function I will discuss next.

Now to define the export func.

You create the exporter from your asset and desired file format. Here I’m using the Apple lossless format.
Then I set the exporter’s outputURL property to a file URL in the documents directory. This will be the location of the trimmed audio file.

I create a core media time range using CMTimeRangeFromTimeToTime that specifies the time offsets for the beginning and ending for the trimmed file. Here I just hard code the values, but of course you’d use a slider or a waveform view to choose the time boundaries.

While you’re there, you can also specify an AVMutableAudioMix for the volume. You can even specify a volume ramp.

Once the exporter’s properties are set, you call exportAsynchronouslyWithCompletionHandler to do the actual work. You can check the status of the export in the completion handler.

Groovy, huh?


Table of Contents

To trim an audio (or video) file, use AVFoundation’s AVAssetExportSession.


Table of Contents

Posted in Computer Music, Core Audio, Swift | Tagged , | 1 Response

Swift 2 OptionSetType

Swift Language

Swift 2 OptionSetType

Swift 2/iOS 9 broke my calendar/date code.
What’s going on?


Table of Contents

If you have an app that does anything with dates, you most likely have code someplace like this.
You get the date’s components, do something with them, and construct a new date from those components.

Broken in iOS 9.
So, the first thought I had was “Did they change the damn names again?” (MonthCalendarUnit for example was previously renamed CalendarUnitMonth).
No, that’s not it. Sort of.

What they did away with was that bitwise or-ing of components.

You do this now to specify the components.

So, MonthCalendarUnit -> CalendarUnitMonth -> Month?
There’s a “bit” more to it.


Table of Contents

The “old” NSCalendarUnit is a RawOptionSetType.
Here is an example definition of options for a hoagie (not a sub – in spite of what The Google says – which are inferior. Hey, the name even implies “sub”standard!).

There’s some boilerplate setup funcs because of the inheritance thing, and then the individual options are defined by bit shifting 1 to create a bitmask.

This is how you would use these options. To set an option, you bitwise-or them into a variable.

You can see if an option is set by doing a bitwise-and like this.

Just like everywhere else you deal with bits. Or to set, And to get, Shift to create masks.


Table of Contents

The new! and improved! way in Swift 2 is to use OptionSetType instead of RawOptionSetType.
No bits, just values. You can even define “aggregate” options like “TheWorks” in this example.

And then to use them in our domain struct:

As you see, OptionSetType provides several funcs for operating on the options.
Is this easier than dealing with bits?
Well, I still use The Emacs, so I’m the wrong guy to ask.

Some Other examples

Table of Contents

Here are a few more places you might find these new option sets.

UIViewAutoresizing is an OptionSetType.

UIUserNotificationType is an OptionSetType.

You will find many more examples and you try to run your old pre 2.0 code.


Table of Contents

OptionSetType has replaced RawOptionSetType.
You don’t have to deal with bit level operations now.
At least, not for options.


Table of Contents

Github repository

OptionSetType documentation

SetAlgebraType protocol

Do you want a really good hoagie?
Amato Brothers Deli
They aren’t paying me for this plug. I just eat there all the time.

Posted in Swift | Tagged , | Leave a comment

Swift 2 AVAudioSequencer

Swift Language

Swift 2 AVAudioSequencer

There’s a brand new MIDI sequencer class in Swift 2 beta! It’s the AVAudioSequencer.


Table of Contents

At WWDC15 there was a presentation entitled “What’s New in Core Audio“. If you were able to get past the first 29 minutes of a poorly structured presentation delivered by a robotic mumbling developer who just reads the lines in the slides (just like 90% of other WWDC presentations), you heard about this. But then, just like every other WWDC presentation, there were incomplete code snippets.

So can we get this to work?

Sequencer setup

Table of Contents

You can play a MIDI file with the old AVMIDIPlayer class. I published a post on this back in the stone age of Swift.

Here is the old Swift 1.2 code to create one. (Swift 2 has updated the old NSError cha cha.)

Swift 2 now has a new AVAudioSequencer class.
Woo Hoo!

Ok, let’s make an AVAudioSequencer!

I’ll talk about the AVAudioEngine set up next.

So, I load a standard MIDI file that I created in Sibelius, tell the sequencer to read it, then start the sequencer. The API doesn’t look too bad at this point.

AVAudioEngine setup

Table of Contents

Let’s create the engine. According to the presentation, there doesn’t need to be much more than a sampler in the engine and the totally groovy new AVAudioSequencer will find it.

That’s all – according to the ‘AudioEngine’er’s presentation.
Good to go, right?
That should be it. But it’s not.
What do you get?

The ‘rioc” is the outputNode. See it?
See that the mixer, ‘mcmx’, is an input to it?
See that the sampler, ‘samp’, is connected to the mixer?
See that the formats are all the same?
The processing graph looks ok. Right?

But then….

So, “required condition is false: outputNode”.
BTW, not to be a grammar nazi, but where is the predicate in that sentence? outputNode what? It’s nil? It’s not there? It’s drunk? outputNode what?

I see the node in the graph. So, what’s the problem?

I have no idea. There is no place to look either.

I’ve tried loading the soundbank – or not.

I’ve set up the session for playback – or not.
I’ve tried with the engine running – or not.
I’ve tried with different MIDI files.
I’ve tried just connecting the sampler to the outputNode. No luck. Shouldn’t have to do that anyway.



Table of Contents

Ok, let’s try the spiffy new AVMusicTrack which is so full of grooviosity that we can retire the old worn out MusicTrack from the AudioToolbox.

Right. No such luck.

I see it defined right there in AVAudioSequencer.h.
Yes, the frameworks are in the project.

Show stopper.

I see that AVAudioSequencer’s definition is preceded by the available macro, but AVMusicTrack doesn’t have that.
Is that the problem?
I’m guessing and do not have the access to try it.

So, once that’s fixed, is there an easy API to add/remove all kinds of MIDI events? You know, channel messages, sysex, controllers, metatext etc.?


Nothing like that.
Mute, solo, length, set a destination, looping.



Table of Contents
In beta 3 it finally stopped crashing. The Github project runs.
The API for AVMusicTrack is still a waste of time though.


Table of Contents

So now we can do away with the AudioToolbox MusicSequence?

So now we can do away with the AudioToolbox MusicTrack?

So now we can connect to an AVAudioEngine without messing around with AudioUnits?

So can we code a simple hello world with this API?

Now that’s what I call progress.


Table of Contents

Posted in Apple, Computer Music, Core MIDI, MIDI, Swift | Tagged , | 10 Responses

Swift 2 and CoreMIDI

Swift Language

Swift 2 and CoreMIDI

Swift 1.2 is notorious regarding its lack of function pointers to deal with C APIs such as Core MIDI. I’ve complained^H^H^H^H^H written about this several times.


Well, praise Zeus, Thor, and the FSM, in Swift 2 beta, Core MIDI is easier to use without function pointers or trampolines.

MIDI Client

Table of Contents

The first step in using CoreMIDI is to create a MIDIClient reference. To do that, you use MIDIClientCreate() which takes a function pointer among other parameters. That is the problem. Swift 1.2 barfs on C function pointers.

The solution in Swift 2 (beta) is the introduction of MIDIClientCreateWithBlock() which will take a closure of type MIDINotifyBlock. This is quite similar to the Objective-C trampoline (but without the Objective-C). Take a look at the naming in my old trampoline code and tell me I’m not a mind reader :)

Well, sort of.
What are you going to do with that MIDINotification?

The different types of notifications are different unrelated structures.

You cannot downcast these via as?

Previously, I simply used unsafeBitCast. That does not work anymore directly. You need to use withUnsafePointer like this:

Yeah, I know.
But it works.

By the way, MIDIClientCreate has been updated too as well as the definitions of the callbacks.

Input Port

Table of Contents

Similarly, MIDIInputPortCreate() which also takes a function pointer (to a read proc) has been upgraded to MIDIInputPortCreateWithBlock() which will take a MIDIReadBlock.

And the read block:

As you can see, iterating trough the packets has not been changed much. Swift does have MIDIPacketNext now though. It was MIA previously.

Personally, I think that if it were a SequenceType it would be much easier. You could do this:

Dream on.

Instead, you have to do some pointer nonsense. And the packets are a tuple, not an array. This example is one way to navigate the list. If you have something more elegant, let me know.

MIDIInputPortCreate() and the read function have also been updated in Swift 2 beta.

Virtual Destination

Table of Contents

To create a Virtual Destination, there is now MIDIDestinationCreateWithBlock() which also takes a MIDIReadBlock.

Remember that you have to edit your Info.plist and add the key “Required Background Modes” with the value set to audio (It will say “App plays audio or streams audio/video using AirPlay”) to create virtual destinations.


Table of Contents

Several new CoreMIDI functions have been added to Swift 2 beta. Here they are:

  • MIDIClientCreateWithBlock()
  • MIDIInputPortCreateWithBlock()
  • MIDIDestinationCreateWithBlock()
  • MIDIReadBlock
  • MIDINotifyBlock
  • MIDIPacketNext()

As always, there is my complete working example project on Github.

Have fun.


Table of Contents

Posted in Core MIDI, Swift | Tagged , | 9 Responses