Live coding session by @yrezgui
NSURL* fileUrl = [NSURL fileURLWithPath:fullPath];
NSDictionary* settings = @{
AVEncoderAudioQualityKey: [NSNumber numberWithInt:AVAudioQualityHigh],
AVSampleRateKey: [NSNumber numberWithInt:48000],
AVNumberOfChannelsKey: [NSNumber numberWithInt:2],
};
The most painful part is the UI and fortunately, we do it in JavaScript
For the rest, ReactJS is implementing slowly but surely more and more APIs
nvm install iojs
nvm alias default iojs
brew install watchman
npm install -g react-native-cli
react-native init AugustMeetup
// AudioRecorder.h
#import "RCTBridgeModule.h"
@interface AudioRecorder : NSObject <RCTBridgeModule>
@end
// AudioRecorder.m
@implementation AudioRecorder
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(log:(NSString *)text)
{
RCTLogInfo(@"Log me that bro: %@", text);
}
@end
// index.ios.js
var React = require('react-native');
var Modules = React.NativeModules;
var AudioRecorder = Modules.AudioRecorder;
AudioRecorder.log('React meetup is so cool');
// AudioRecorder.h
#import <AVFoundation/AVFoundation.h>
// AudioRecorder.m
@implementation AudioRecorder {
AVAudioRecorder *_audioRecorder;
}
...
RCT_EXPORT_METHOD(setup:(NSString *)filename callback:(RCTResponseSenderBlock)callback)
{
NSLog(@"file URL: %@", filename);
callback(@[fullPath]);
}
// AudioRecorder.m
AVAudioSession *_audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[_audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if (err) {
NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
return;
}
err = nil;
[_audioSession setActive:YES error:&err];
if (err) {
NSLog(@"audioSession: %@ %ld %@", [err domain], [[err userInfo] description]);
return;
}
// AudioRecorder.m
- (NSString *) applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
...
RCT_EXPORT_METHOD(setup:(NSString *)
...
NSString* fullPath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:filename];
NSURL* fileUrl = [NSURL fileURLWithPath:fullPath];
// AudioRecorder.m
@implementation AudioRecorder {
AVAudioRecorder *_audioRecorder;
}
...
RCT_EXPORT_METHOD(setup:(NSString *) {
...
NSLog(@"file URL: %@", fullPath);
NSDictionary* settings = @{
AVEncoderAudioQualityKey: [NSNumber numberWithInt:AVAudioQualityHigh],
};
err = nil;
_audioRecorder = [[AVAudioRecorder alloc] initWithURL:fileUrl settings:settings error:&err];
[_audioRecorder prepareToRecord];
callback(@[fullPath]);
}
// AudioRecorder.m
RCT_EXPORT_METHOD(start)
{
[_audioRecorder record];
}
RCT_EXPORT_METHOD(stop)
{
[_audioRecorder stop];
}
// Add in the implementation
AVAudioPlayer *_audioPlayer;
...
RCT_EXPORT_METHOD(play:(NSString *)filename)
{
NSError *error;
NSString* fullPath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:filename];
NSURL* fileUrl = [NSURL fileURLWithPath:fullPath];
_audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:_audioRecorder.url
error:&error];
if (error) {
NSLog(@"play audio error: %@", [error localizedDescription]);
} else {
[_audioPlayer play];
}
}
Example project with React Native
https://github.com/yrezgui/meowth-ios