I think I found my issue.
The original code with the problem:
// Start
OSStatus status = AudioOutputUnitStart(self.ioUnit);
// Record the audio samples and save it to a file
[self createFile];
The new code that fixed the problem. Notice the "createFile" is called first before calling AudioOutputUnitStart
// Record the audio samples and save it to a file
[self createFile];
// Start
// Once AudioOutputUnitStart is called, it will start calling callback method quickly. We need to call the above [self createFile] first.
OSStatus status = AudioOutputUnitStart(self.ioUnit);
The AudioOutputUnitStart calls the callback method which will write audio samples to a file. Since the file has been created/opened before AudioOutputUnitStart, now the audio samples are written to the file without any error.