Swift开发:如何通过字符串变量调用AudioKit的TableType枚举
问题:如何通过字符串变量获取AudioKit的TableType枚举值?
我正在用AudioKit开发应用,现有代码能生成持续1秒的平滑低频音调:
let osc = DynamicOscillator(amplitude: 0) let audioEngine = AudioEngine() audioEngine.output = osc do { try audioEngine.start() osc.amplitude = 0 osc.start() } catch { print("could not start audioengine") } osc.$frequency.ramp(to: frequency, duration: 0.5) osc.$amplitude.ramp(to: 1, duration: 0.5) osc.setWaveform(Table(.sine)) DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { osc.$amplitude.ramp(to: 0, duration: 0.5) }
现在想让用户选择波形,需要从字符串变量读取波形类型,比如:
var waveform = "sine" osc.setWaveform(Table(waveform))
但这段代码无法运行,因为Table的初始化方法需要传入TableType枚举值,该枚举的初始化逻辑如下:
public init(_ type: TableType = .sine, phase: Float = 0, count: IndexDistance = 4096) { self.type = type self.phase = phase content = [Element](zeros: count) switch type { case .sine: standardSineWave() case .sawtooth: standardSawtoothWave() // 其他波形case省略 [...] }
解决方案
方法一:给TableType扩展字符串初始化方法
给TableType枚举添加一个可失败初始化器,直接把字符串转成对应的枚举值:
extension TableType { init?(stringValue: String) { // 转成小写避免大小写匹配问题 switch stringValue.lowercased() { case "sine": self = .sine case "sawtooth": self = .sawtooth case "square": self = .square case "triangle": self = .triangle // 补充AudioKit支持的其他波形类型 default: return nil } } }
使用时先判断字符串是否有效,无效则用默认波形兜底:
var waveformString = "sine" if let waveformType = TableType(stringValue: waveformString) { osc.setWaveform(Table(waveformType)) } else { // 字符串无效时默认用正弦波 osc.setWaveform(Table(.sine)) }
方法二:用字典做字符串-枚举映射
如果不想扩展枚举,也可以直接用字典建立字符串和枚举值的对应关系:
// 定义字符串到枚举的映射表 let waveformMap: [String: TableType] = [ "sine": .sine, "sawtooth": .sawtooth, "square": .square, "triangle": .triangle ] var waveformString = "sine" // 用空合运算符处理无效字符串,默认返回正弦波 let waveformType = waveformMap[waveformString.lowercased()] ?? .sine osc.setWaveform(Table(waveformType))
两种方法都能解决问题:扩展初始化器的方式更符合Swift的枚举设计规范,字典映射则更简洁直观,适合快速实现。
内容的提问来源于stack exchange,提问作者n.r.
相关产品推荐
相关产品推荐

