Search code examples
swiftaudiokit

How to use AudioKit in SwiftUI? Change state var in view


I have added a listener:

class MIDIReceiver: MIDIListener {
...
}

Where should I put the following code in SwiftUI so that I can use my midi keyboard to change the @State var ?

let midi = MIDI()
midi.openInput()
let receiver = MIDIReceiver()
midi.addListener(receiver)

Thank you

-- Added Oct 28 --

(1) I added the class in https://github.com/AudioKit/Cookbook/blob/main/Cookbook/Cookbook/Recipes/MIDIMonitor.swift but without the view...

After adding @ObservedObject var conductor = MIDIMonitorConductor() in my ContentView, these show in my console.

2020-10-28 00:47:19.646934-0500 AudioKitTrySPM[2998:82471] [midi] MIDI.swift:init():52:Initializing MIDI (MIDI.swift:init():52) 2020-10-28 00:47:19.698885-0500 AudioKitTrySPM[2998:82471] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600000211300> F8BB1C28-BAE8-11D6-9C31-00039315CD46 2020-10-28 00:47:19.728062-0500 AudioKitTrySPM[2998:82471] HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine

Should I change anything else in the project?

(2) I have an State array in my contentview

    @State private var touchKeys: Array<Bool> = [Bool](repeating: false, count: 24)

How do I trigger a function to map the midi signal to update the array?

Thank you


Solution

  • You can make your receiver ObservableObject and use published properties for values/states you want your SwiftUI view depend/refresh on.

    Like in below example:

    import Combine
    
    class MIDIReceiver: MIDIListener: ObservableObject {
       @Published var midiSignalReceived = false
    
       private let midi: MIDI!
    
       func setup() {
         midi = MIDI()
         midi.openInput()
         midi.addListener(self)
       }
    
       // ... other code / midi callbacks here
    }
    
    // ...
    
    struct ContentView: View {
      @StateObject var midiListener = MIDIListener()
    
      var body: some View {
         Text("Root View")
           .onReceive(midiListener.$midiSignalReceived) { activated in
               // do something here
           }
           .onAppear {
              self.midiListener.setup()
           }
      }
    }
    

    See the example events/states in AudioKit iOS - receivedMIDINoteOn function