I'm creating an iOS app with the functionality to record audio for several minutes. I need to have some kind of auto save function every 10/20/30 seconds to have a fallback for when the app crashes / incoming phone calls / closing app completely.
What I've tried already:
- I tried to work with the file after a crash, I could see the file in iTunes & play it on my MacBook but I couldn't play it in the app anymore (probably not saved in the right way?)
- I tried duplicating the file while recording but the duplicate was also not workable (probably the same reason?)
- Saving the file every .. seconds was not possible at all
- I've tried to detect the moment the app was crashing/closed and then save the file quickly and store it locally. This was working but wasn't reliable enough that all the code was executed before the app went in to the background.
How can I make some sort of auto-save function so I always have a fallback for the recorded audio file??
I'm recording the audio with the AVAudioRecorder and AVAudioSession. Exporting the audio file (when done or when crashing/closing) is done with an AVMutableComposition and AVAssetExportSession.
Here is some of my code for initialising the AVAudioRecorder:
self.recorder = [[AVAudioRecorder alloc] initWithURL:filePath settings:_recordSetting error:NULL];
self.recorder.delegate = self;
self.recorder.meteringEnabled = YES;
[self.recorder prepareToRecord];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
And here is how I export the audio:
AVMutableComposition* composition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *audioCombinedTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[audioCombinedTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [audio1 duration]) ofTrack:[audio1.tracks objectAtIndex:0] atTime:kCMTimeZero error:&error];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
NSString *latestFileName = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]];
NSString *exportPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.wav", latestFileName]];
_exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = _exportURL;
exportSession.outputFileType = AVFileTypeWAVE;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (@"Exporting. status is %ld", (long)exportSession.status);
switch (exportSession.status) {
case AVAssetExportSessionStatusFailed:
NSLog(@"export failed");
break;
case AVAssetExportSessionStatusExporting: {
NSLog(@"export exporting");
break;
}
case AVAssetExportSessionStatusCancelled: {
NSLog(@"export cancelled");
break;
}
case AVAssetExportSessionStatusWaiting: {
NSLog(@"export waiting");
break;
}
case AVAssetExportSessionStatusUnknown: {
NSLog(@"export unknown");
break;
}
case AVAssetExportSessionStatusCompleted: {
NSLog(@"export done");
break;
}
};
}];
Note: when using the app (so just recording and stopping the recorder) the audio files are created correctly and everything works fine.