Reputation: 1012
Xcode 8 beta 2 / Swift 3:
According to Apple's CoreMIDI API documentation, a MIDI thru connection can be established as persistent (stays in place forever, even after your app quits and your system reboots) or non-persistent/transitory (owned by your application and automatically destroys it on app quit).
The trouble I'm running into is that I can't seem to create a non-persistent connection, even though I am following Apple's guidelines.
It comes down to this API:
func MIDIThruConnectionCreate(_ inPersistentOwnerID: CFString?,
_ inConnectionParams: CFData,
_ outConnection: UnsafeMutablePointer<MIDIThruConnectionRef>) -> OSStatus
If you pass null (nil
) to inPersistentOwnerID
which is a Swift optional, the connection should be created as transitory. However, regardless of whether I pass nil or a String, connections are always created as persistent. (I can verify this by checking CoreMIDI's persistent thru connections.)
A summation of my code:
public class OTMIDIConnectedThru {
var connectionRef = MIDIThruConnectionRef()
init?(sourceEndpoints: [MIDIEndpointRef], destinationEndpoints: [MIDIEndpointRef], persistentOwnerID: String? = nil) {
var params = MIDIThruConnectionParams()
MIDIThruConnectionParamsInitialize(¶ms) // fill with defaults
// (... snip: code to prepare parameters here ...)
let paramsData = withUnsafePointer(¶ms) { p in
NSData(bytes: p, length: MIDIThruConnectionParamsSize(¶ms))
}
result = MIDIThruConnectionCreate(persistentOwnerID, paramsData, &connectionRef)
guard result == noErr else { return nil }
}
}
Any idea what I'm doing wrong? This couldn't possibly be a bug in the API?
Upvotes: 2
Views: 255
Reputation: 96
I had the same issue, and yes I think it always does create persistent connections. Probably an ID of NULL is the same as an empty string, because MIDIThruConnectionFind with an empty string returns all those persistent connections. So, a bug in the API or the docs!
I would recommend using a real persistentID, and remove all existing/stale connections when you initialize your MIDI stuff:
CFDataRef data;
MIDIThruConnectionFind(CFSTR("com.yourcompany.yourapp"), &data);
unsigned long n = CFDataGetLength(data) / sizeof(MIDIThruConnectionRef);
MIDIThruConnectionRef * con = (MIDIThruConnectionRef*)CFDataGetBytePtr(data);
for(int i=0;i<n;i++) {
MIDIThruConnectionDispose(*con);
con++;
}
Upvotes: 1