How to send high-quality voice on iOS

1. Set audio recording settings

NSDictionary *recordSettings = @{
    AVFormatIDKey : @(kAudioFormatMPEG4AAC_HE),
    AVNumberOfChannelsKey : @1,
    AVEncoderBitRateKey : @(32000)
};

2. Generate temporary voice file path

NSURL *recordTempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() 
                                      stringByAppendingPathComponent:@"HQTempAC.m4a"]];

3. Record high-quality voice message

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
[audioSession setActive:YES error:nil];

NSError *error = nil;
if (self.recorder == nil) {
    AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:recordTempFileURL 
                                                          settings:recordSettings error:&error];
    recorder.delegate = self;
    recorder.meteringEnabled = YES;
}

// Prepare to record
[recorder prepareToRecord];
// Start recording
[recorder record];

4. Publish voice message after recording

if (!recorder.url) { return; }

NSURL *url = [[NSURL alloc] initWithString:recorder.url.absoluteString];

// Current recording duration
NSTimeInterval audioLength = recorder.currentTime;

// Stop recording
[recorder stop];

// Recording file data
NSData *currentRecordData = [NSData dataWithContentsOfURL:url];

recorder = nil;

// Move voice from temporary path to permanent path
NSString *path = [self getHQVoiceMessageCachePath];
[currentRecordData writeToFile:path atomically:YES];

// Construct high-quality voice message
RCHQVoiceMessage *hqVoiceMsg = [RCHQVoiceMessage messageWithPath:path duration:audioLength];

// Send message
RCMessage *message = [[RCMessage alloc] initWithType:ConversationType_PRIVATE targetId:@"2" 
                                            direction:MessageDirection_SEND content:hqVoiceMsg];

[[RCCoreClient sharedCoreClient] sendMediaMessage:message pushContent:nil pushData:nil 
                                        progress:^(int progress, RCMessage *progressMessage){}
                                    successBlock:^(RCMessage *successMessage) {
                                        NSLog(@"--- Message sent successfully");
                                    } 
                                    errorBlock:^(RCErrorCode nErrorCode, RCMessage *errorMessage) {
                                        NSLog(@"--- Message sending failed %ld", nErrorCode);
                                    } cancel:^(RCMessage *cancelMessage) {}];

// Local path for voice message
- (NSString *)getHQVoiceMessageCachePath {
    long long currentTime = [[NSDate date] timeIntervalSince1970] * 1000;

    // Path
    NSString *path = [RCUtilities rongImageCacheDirectory];
    path = [path stringByAppendingFormat:@"/%@/RCHQVoiceCache", [RCIMClient sharedRCIMClient].currentUserInfo.userId];

    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:path 
                                  withIntermediateDirectories:YES 
                                                   attributes:nil 
                                                        error:nil];
    }

    NSString *fileName = [NSString stringWithFormat:@"/Voice_%@.m4a", @(currentTime)];
    path = [path stringByAppendingPathComponent:fileName];

    NSLog(@"--- path %@", path);

    return path;
}