React Native modules
Live coding session by @yrezgui
Yacine Rezgui
ReactJS + iOS =
But Objective-C....
NSURL* fileUrl = [NSURL fileURLWithPath:fullPath];
NSDictionary* settings = @{
AVEncoderAudioQualityKey: [NSNumber numberWithInt:AVAudioQualityHigh],
AVSampleRateKey: [NSNumber numberWithInt:48000],
AVNumberOfChannelsKey: [NSNumber numberWithInt:2],
};
Don't freak out!
It's just code
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
Demo ?
We are going to record
an audio file and play it
Forget to install React Native?
nvm install iojs
nvm alias default iojs
brew install watchman
npm install -g react-native-cli
react-native init AugustMeetup
Step 1
Create button
and click handler
Step 2
Create a simple native module
Step 2
// 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');
Step 3
Import
AVFoundation
Step 3
// 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]);
}
Step 4
Initialise AudioSession
Step 4
// 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;
}
Step 5
Generate the fullpath of the file
Step 5
// 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];
Step 6
Setup AudioRecorder instance
Step 6
// 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]);
}
Step 7
Start and stop
recording
Step 7
// AudioRecorder.m
RCT_EXPORT_METHOD(start)
{
[_audioRecorder record];
}
RCT_EXPORT_METHOD(stop)
{
[_audioRecorder stop];
}
Step 8
Freestyle moment
Step 9
Still have time ?
Play the audio
Step 9
// 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];
}
}
Thank you !
@yrezgui
Example project with React Native
https://github.com/yrezgui/meowth-ios
By the way, I'm available for hire yrezgui.com
React Native modules - Live coding session
By Yacine Rezgui
React Native modules - Live coding session
- 2,063