Swift Playgrounds中获取外接MIDI设备名称失败求助
Swift Playgrounds中MIDI设备无法识别的修复方案
你的代码无法获取MIDI设备列表的核心原因是未初始化CoreMIDI客户端——CoreMIDI要求必须先创建一个活跃的MIDI客户端,才能枚举系统中的MIDI设备。直接调用MIDIGetNumberOfDevices会返回0,因为没有客户端上下文。
修复后的完整代码
import SwiftUI import CoreMIDI struct ContentView: View { @State private var selectedDevice: String = "" @State private var deviceList: [String] = [] var body: some View { VStack { TextField("Selected Device", text: $selectedDevice) .padding() Button("Select Device") { self.deviceList = getMIDIDeviceList() } .padding() // 新增:展示获取到的设备列表,支持点击选择 List(deviceList, id: \.self) { name in Text(name) .onTapGesture { selectedDevice = name } } } } private func getMIDIDeviceList() -> [String] { var deviceNames = [String]() var midiClient: MIDIClientRef = 0 let clientName = "MIDIDeviceScanner" as CFString // 1. 创建MIDI客户端,这是枚举设备的必要前提 let createResult = MIDIClientCreate(clientName, nil, nil, &midiClient) guard createResult == noErr else { print("创建MIDI客户端失败:\(createResult)") return deviceNames } // 2. 枚举所有MIDI设备并提取名称 let numberOfDevices = MIDIGetNumberOfDevices() for index in 0..<numberOfDevices { let device = MIDIGetDevice(index) var name: Unmanaged<CFString>? let propertyResult = MIDIObjectGetStringProperty(device, kMIDIPropertyName, &name) if propertyResult == noErr, let name = name { deviceNames.append(name.takeUnretainedValue() as String) name.release() // 释放Unmanaged对象,避免内存泄漏 } } // 3. 销毁客户端(若需持续监听设备可保留客户端实例) MIDIClientDispose(midiClient) return deviceNames } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
关键修改说明
- 初始化MIDI客户端:通过
MIDIClientCreate创建客户端上下文,这是CoreMIDI访问设备的硬性要求,没有客户端则无法获取任何设备信息。 - 错误检查:添加客户端创建和属性读取的错误判断,便于排查异常情况。
- 内存管理:调用
name.release()释放Unmanaged<CFString>对象,避免内存泄漏。 - 可视化设备列表:新增
List组件展示获取到的设备,解决原代码仅用TextField无法查看结果的问题。
额外提示
- 确保iPad已正确连接MIDI设备(蓝牙或有线),且设备处于活跃状态。
- 若需要实时监听设备连接/断开事件,可通过
MIDINotificationCreate注册通知回调,替代手动点击枚举的方式。
内容的提问来源于stack exchange,提问作者Jpm47
相关产品推荐
相关产品推荐

