Before, I worked on app development related to React Native and did some interesting things. I have always wanted to write something for record. This time, I plan to write three entry-level articles in the same demo running on ios.

Code:DEMO

/ / run the demo $git clone https://github.com/lianglei777/demos.git $CD demos $git checkout CD RNFaceDemo RNFaceDemo $$ npm install $ cd ios $ pod installCopy the code

Environment set up

Here is mainly about the problems I encountered when setting up the environment

The react-Native base environment can be set up for referencewebsite

cocoapods

Ios cocoapods installation and the related command pod install may need to scientific Internet access, otherwise there is a high probability of failure, you can also consider changing the source, method is as follows

$ cd ~/.cocoapods/repos $ pod repo remove master <! - tsinghua source - > $git clone master < https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git! - Beijing foreign studies university, I am currently in use - > $git clone master < https://mirrors.bfsu.edu.cn/git/CocoaPods/Specs.git! -- gitclub --> $ git clone https://gitclub.cn/CocoaPods/Specs.git masterCopy the code

The current development environment

When installing the environment, I did feel the difference between MAC OS versions (the previous demo didn’t work), here is the current development environment

MacOS: 12.0 Monterey Node: 14.16.0 Xcode: 12.5 Cocoapods: 1.10.1Copy the code

PS: I think the React Native environment setup is a bit of a hurdle for newcomers, especially those without iOS or Android development experience. Please read the tutorials on the react Native website carefully.

Js actively calls the method defined natively by ios and returns the parameter to JS

Create the RNManager class file in the ios project. The default file name of the react Native bridge components and methods must end with Manager. The content of the document is as follows:

RNManager.h

#import <Foundation/Foundation.h> #import <React/RCTBridge.h> #import <React/RCTConvert.h> #import <React/RCTBridgeModule.h> // 1. You must inherit the RCTBridgeModule protocol and import the necessary headers @interface RNManager: NSObject<RCTBridgeModule> @endCopy the code

RNManager.m

#import "rnManager. h" #import" appdelegate. h" @implementation RNManager // 2.. m To expose the class to RN RCT_EXPORT_MODULE(); // 3. This method determines which thread the bridge method runs on, usually the main thread. If UI changes are involved, - (dispatch_queue_t)methodQueue {return dispatch_get_main_queue(); } // 4. RCT_REMAP_METHOD is the bridge method // sendMegToNative: Used in rn method name / / one, two, three, successCallBack, errorCallBack is ginseng / / similar sendMegToNative (one, two, three, (success) = > {}, (error) => {}), // Use the ios notation for common types. Js is string, number, bool, etc. The method must be of type RCTResponseSenderBlock. The callback parameter must be wrapped in an array. The content type must refer to the iOS syntax. RCTPromiseResolveBlock, RCTPromiseRejectBlock, RCTPromiseRejectBlock, RCTPromiseRejectBlock, RCTPromiseRejectBlock Callback and promise don't mix,  RCT_REMAP_METHOD(sendMegToNative, :(NSString *)one :(NSString *)two :(NSString *)three :(RCTResponseSenderBlock)successCallBack :(RCTResponseSenderBlock)errorCallBack ){ NSString *title = one; NSString *message = two; NSString *cancelButtonTitle = @" cancelButtonTitle "; NSString *otherButtonTitle = @" OK "; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel Handler :^(UIAlertAction *action) {if(! ErrorCallBack){return;} UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault Handler :^(UIAlertAction *action) {if(! SuccessCallBack){return;} }]; [alertController addAction:cancelAction]; [alertController addAction:otherAction]; AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; [delegate.window.rootViewController presentViewController:alertController animated:YES completion:nil]; } @endCopy the code

Please pay attention to points 1, 2, 3 and 4 above. The implementation of this method is the normal object-C syntax. The following is called in JS

FunctionBridgeDemo.js

import React, {PureComponent} from 'react';
import {
  View,
  Button,
  StyleSheet,
  NativeModules,
} from 'react-native';

// RNManager is the name of the bridge RNManager object in ios
const { RNManager } = NativeModules;

export default class FunctionBridgeDemo extends PureComponent {

  sendMsgToNative = () = > {
    // Call the sendMegToNative method of the native bridge, passing arguments and calling back
    RNManager.sendMegToNative(
      'Just a heads up'.'Are you going to study RN? '.'333'.result= > {
        console.log('success return == ', result);
      },
      error= > {
        console.log('Error return ==', error); }); };render() {
    return (
      <View style={styles.container}>
        <Button title="Hello Native" onPress={this.sendMsgToNative} />
      </View>); }}Copy the code

The above is the normal react Native encapsulation method, which is called in the JS layer. If you want to know the encapsulation method of Promise, see the annotation section of related methods in demo.

Native actively sends messages to JS

Create the EventEmitManager class file in ios project by encapsulating listening events.

EventEmitManager.h

#import <Foundation/ foundation. h> #import <React/ rctbridgemodule. h> #import <React/ rcteventemt. h> // inherit Interface EventEmitManager: RCTEventEmitter<RCTBridgeModule> @endCopy the code

EventEmitManager.m

#define NATIVE_TO_RN_ONNOFIFICATION @"onNotification" #define NATIVE_TO_RN_ONNOFIFICATION @"onNotification" #import "eventemitManager. h #define NATIVE_ONNOFIFICATION @"native_onNotification" @implementation EventEmitManager{ bool hasListeners; } // export module RCT_EXPORT_MODULE() // key exposed to JS listening -(NSArray*)supportedEvents {return@[NATIVE_TO_RN_ONNOFIFICATION]; } - (void)nativeSendNotificationToRN:(NSNotification*)notification { NSLog(@"NativeToRN notification.userInfo = %@", notification.userInfo); if (hasListeners) { [self sendEventWithName:NATIVE_TO_RN_ONNOFIFICATION body:notification.userInfo]; }} // Overriding startObserving {hasListeners = YES; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nativeSendNotificationToRN:) name:NATIVE_ONNOFIFICATION object:nil]; } // Write the listeners to the listeners, js - (void) stoplisteners {hasListeners = NO; [[NSNotificationCenter defaultCenter] removeObserver:self name:NATIVE_ONNOFIFICATION object:nil]; } @endCopy the code

< span style = “max-width: 100%; clear: both; min-height: 1pt;

This can be added in the ios project’s Appdelegate. m declaration cycle method, and the corresponding trigger method is shown below

AppDelegate.m

. / / the foreground in the background - (void) applicationWillResignActive: (UIApplication *) application {[[NSNotificationCenter defaultCenter] postNotificationName:@"native_onNotification" object:nil userInfo:@{@"lifeState": @"WILL_GO_BACKGROUD"}]; }...Copy the code

Js implemented

FunctionBridgeDemo.js

const eventEmitManagerEmitter = new NativeEventEmitter(EventEmitManager); . This. Subscription = eventEmitManagerEmitter. AddListener (' onNotification 'reminder = > {the console. The log (' listening = = ", reminder); }); . componentWillUnmount() { this.subscription && this.subscription.remove(); }Copy the code

When entering the background in the app foreground, there will be relevant monitoring logs, so we must pay attention to the distinction of key, please refer to the demo for details.

summary

The above two methods of the value in the website can be found, but new to the classmate of RN, usually only one of the familiar with native and js, it sometimes will have the confusion of understanding, and sometimes website example was “not detailed enough, according to official website when writing code cannot reach the desired effect, such as written in the second listening, It doesn’t apply to real life (at least I did). So MY demo code as far as possible to write detailed, so that readers can “copy” the past, simple change can be used.

If you have any questions please leave them in the comments section

  • React Native js and ios value transfer
  • React Native packs face detection and beauty components
  • React Native WebView usage scenarios