2016-07-14 8 views
2

Xcode 8 Beta 2/Swift 3:MIDIThruConnectionCreate erstellt immer persistente MIDI-Thru-Verbindung?

Nach Apple's CoreMIDI API documentation, ein MIDI Thru-Verbindung kann als persistent festgelegt werden (für immer bleibt an seinem Platz, auch nach Ihrer Anwendung beendet und das System neu gestartet wird) oder nicht-persistent/vorübergehend (im Besitz Ihrer Anwendung und zerstört es automatisch auf App beenden).

Das Problem, das ich renne ist, dass Ich kann nicht scheinen, eine nicht dauerhafte Verbindung zu erstellen, auch wenn ich die Richtlinien von Apple befolge.

Es kommt auf this API:

func MIDIThruConnectionCreate(_ inPersistentOwnerID: CFString?, 
         _ inConnectionParams: CFData, 
         _ outConnection: UnsafeMutablePointer<MIDIThruConnectionRef>) -> OSStatus 

Wenn Sie null (nil) zu inPersistentOwnerID passieren, die ein Swift optional ist, sollte die Verbindung als vorübergehend angelegt werden. Unabhängig davon, ob ich nil oder einen String übergebe, werden Verbindungen immer als persistent erstellt. (Ich kann dies überprüfen, indem Coremidi beharrliche durch Verbindungen zu überprüfen.)

eine Zusammenfassung meines Code:

public class OTMIDIConnectedThru { 
    var connectionRef = MIDIThruConnectionRef() 

    init?(sourceEndpoints: [MIDIEndpointRef], destinationEndpoints: [MIDIEndpointRef], persistentOwnerID: String? = nil) { 
     var params = MIDIThruConnectionParams() 
     MIDIThruConnectionParamsInitialize(&params) // fill with defaults 

     // (... snip: code to prepare parameters here ...) 

     let paramsData = withUnsafePointer(&params) { p in 
      NSData(bytes: p, length: MIDIThruConnectionParamsSize(&params)) 
     } 

     result = MIDIThruConnectionCreate(persistentOwnerID, paramsData, &connectionRef) 
     guard result == noErr else { return nil } 
    } 
} 

Jede Idee, was ich falsch mache? Dies könnte möglicherweise kein Fehler in der API sein?

Antwort

1

Ich hatte das gleiche Problem, und ja, ich denke, es schafft immer dauerhafte Verbindungen. Wahrscheinlich entspricht eine ID von NULL einer leeren Zeichenfolge, da MIDIThruConnectionFind mit einer leeren Zeichenfolge alle diese persistenten Verbindungen zurückgibt. Also, ein Fehler in der API oder in der Dokumentation!

würde ich empfehlen, eine echte PersistentID verwenden, und entfernen Sie alle vorhandenen/abgestanden Verbindungen, wenn Sie Ihr MIDI-Material initialisieren:

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++; 
} 
+0

Danke für die Antwort. Ich habe darüber nachgedacht, alle Verbindungen mit selbstdefinierten 'persistendID's beim App-Start zu beenden und zu beenden, aber es ist eher eine Art Work-Around und deckt offensichtlich nicht alle Fälle ab, zum Beispiel wenn deine App abstürzen würde verwaiste Verbindungen, die nicht erwünscht sind. Sie haben gesagt, dass Sie in Objective-C nicht in der Lage sind, nicht persistente Verbindungen zu erstellen? Dann würde dies auf einen tatsächlichen oder irreführenden API-Fehler hinweisen und nicht auf einen Fehler in der Swift-API-Wrapper-Ebene. – stef

+0

Die obige Idee ist, alle alten Verbindungen von Ihnen beim App-Start zu bereinigen, bevor Sie neue erstellen. Ich glaube nicht, dass Waisen durch Verbindungen nach dem Absturz der App Schaden anrichten werden, es sei denn, sie werden nur zwischen externen Endpunkten gemacht. Dann ist der "Schaden", dass die Endpunkte immer noch verbunden sind. In einer App, die ich gerade entwickle, mache ich das, was ich oben vorgeschlagen habe. Das funktioniert gut, weil ich nur mit meinen eigenen virtuellen Endpunkten verbunden bin. Wenn also die App abstürzt, sind diese Endpunkte sowieso nicht am Leben. –

+0

eine Idee wie man das in Swift3 macht? Ich kann mir nicht vorstellen, wie man den Zeiger auf das nicht-optionale 'Unmanaged ' erzeugt, das Swift für den zweiten Parameter benötigt – Alnitak