Using CABTMIDILocalPeripheralViewController with SwiftUI

I'm trying to make an app that can send MIDI data over Bluetooth from my iPhone to my Mac. I'm using AudioKit as a framework for the MIDI aspect, and it's working great over a wired connection. I can't figure out how to implement MIDI over Bluetooth though.


I found the

CABTMIDILocalPeripheralViewController page here: https://developer.apple.com/documentation/coreaudiokit/cabtmidilocalperipheralviewcontroller
, which looks promising, but I'm confused about how to use it.


I'd really like to implement it using SwiftUI as opposed to UIKit, because the rest of the app is made with SwiftUI. Could someone please show me how I could use this in SwiftUI to make my iPhone discoverable as a Bluetooth MIDI device?


I found some sample code written with UIKit, but I'd like to translate this to SwiftUI:


import UIKit
import CoreAudioKit
import CoreMIDI

class ViewController: UIViewController {

  var localPeripheralViewController:CABTMIDILocalPeripheralViewController?

  override func viewDidLoad() {
  super.viewDidLoad()
  localPeripheralViewController = CABTMIDILocalPeripheralViewController()
  }

  @IBAction func someAction(sender: AnyObject) {
  self.navigationController?.pushViewController(localPeripheralViewController!, animated: true)
  }
}


Thank you,

Jack

Replies

I have no experience about CABTMIDILocalPeripheralViewController, but it is a subclass of UIViewContoller.

So, you should better try it with `UIViewControllerRepresentable`.


This Apple's tutorial is an example of using UIViewControllerRepresentable.

Interfacing with UIKit


The tutorial itself is too specialized for UIPageViewController and many parts of them are not needed for CABTMIDILocalPeripheralViewController, but it seems it is the only tutorial for UIViewControllerRepresentable.

I'll check it out. Thanks!

I think you would need to use Core MIDI to expose and activate a MIDI Bluetooth port from the iPhone.

UIViewControllerRepresentable

SwiftUI MIDI Bluetooth example

Content View:


	@State private var btScan = false
	@State private var btAdvertise = false

    var body: some View {
        VStack {
			Button("Bluetooth MIDI Scan") { self.btScan = true }
				.sheet(isPresented: $btScan) { BTConnectController(btScan: self.$btScan) }
        	Button("Bluetooth Advertise") { self.btAdvertise = true }
				.sheet(isPresented: $btAdvertise) { BTPeripheralController(btAdvertise: self.$btAdvertise) }
        	}
        .padding()
     }

struct BTConnectController : UIViewControllerRepresentable {
	func makeUIViewController(context: Context) -> CABTMIDICentralViewController {
		CABTMIDICentralViewController()
	}
	
	func updateUIViewController(_ uiViewController: CABTMIDICentralViewController, context: Context) {
		
	}
	typealias UIViewControllerType = CABTMIDICentralViewController
    @Binding var btScan: Bool
}

struct BTPeripheralController : UIViewControllerRepresentable {
	func makeUIViewController(context: Context) -> CABTMIDILocalPeripheralViewController {
		CABTMIDILocalPeripheralViewController()
	}
	
	func updateUIViewController(_ uiViewController: CABTMIDILocalPeripheralViewController, context: Context) {
		
	}
	typealias UIViewControllerType = CABTMIDILocalPeripheralViewController
    @Binding var btAdvertise: Bool
}

Hope it helps, @JSE98

Best regards

Andreas