React Native modules

Live coding session by @yrezgui

Yacine Rezgui

Web Developer

French-Tunisian

I ❤ JavaScript

yrezgui.com

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

Made with Slides.com