var engine:AVAudioEngine!
var format = engine.inputNode.inputFormat(forBus: 0)
engine.connect(engine.inputNode, to: engine.mainMixerNode, format: format)
I figure it out. I just set the AVAudioSession category type wrong. If you have the same error take a look at AVAudioSession and make sure that your AVAudioSession category is in the right setting for microphone permission. for instance
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .mixWithOthers)
with this setting will allow app to use microphone and play sound in the same time.