[React Native] Native Module (iOS)(번역)

공효은·2022년 2월 10일
1

reactNative

목록 보기
8/9

캘린더 네이티브 모듈 만들기

CalendarModule 모듈
Javascript에서 Apple의 캘린더 API에 액세스 할 수 있는 기본 모듈을 만든다.
결국 CalendarModule.createCalendarEvent("Dinner Party", "My House"); 달력 이벤트를 생성하는 기본 메서드를 호출하여 JavaScript에서 호출 할 수 있다.

Custom Native 모듈 파일 생성

첫 번째 단계는 기본 사용자 지정 기본 모듈 헤더와 구현 파일을 만드는 것이다.

다음을 추가한다.

현재 구축 중인 네이티브 모듈에 맞는 이름을 사용 할 수 있다.
캘린더 네이티브 모듈을 만들기 때문에 클래스 이름을 RCTCalendarModule로 지정한다. ObjC는 Java 또는 C++와 같은 네임스페이스에 대한 언어 수준의 지원이 없으므로 클래스 이름 앞에 하위 문자열을 붙인다. 이것은 응용 프로그램 이름 또는 인프라 이름의 약어 일 수 있다. 이 예시에서 RCT는 React를 나타낸다.

네이티브 모듈 구현

RCTCalendarModule.m 동일한 폴더에 해당 구현 파일을 만들고 아래와 같이 입력

Module Name

현재 RCTCalendarModule.m 네이티브 모듈에는 네이티브 모듈 클래스를 내보내고 React Native에 등록하는 RCT_EXPORT_MODULE 매크로만 포함되어있다.
또한, RCT_EXPORT_MODULE 매크로 에는 JavaScript코드에서처럼 모듈에 엑세스 할 수 있는 이름을 지정하는 선택적인 인수가 사용된다.

이 인수는 문자열 리터럴이 아니다. 아래 예에서는 RCT_EXPORT_MODULE("CalendarModuleFoo")이 아닌 RCT_EXPORT_MODULE(CalendarModuleFoo)이 통과됨

그러면 다음과 같이 JS에서 네이티브 모듈에 엑세스 할 수 있다.

const {CalendarModuleFoo} = ReactNative.NativeModules;

이름을 지정하지 않으면 JavaScript 모듈 이름은 "RCT" 또는 "RK" 접두사가 제거된 Object-C 클래스 이름과 일치함

Export a Native Method to JavaScript

React Native는 명시적으로 지시하지 않는 한 네이티브 모듈의 메서드를 JavaScript에 노출하지 않는다.
이 작업은 RCT_EXPORT_METHOD 매크로를 사용하여 수행 할 수 있다.
RCT_EXPORT_METHOD 매크로에 작성된 메서드는 비동기식 이므로 반환 유형은 항상 void 이다.
RCT_EXPORT_METHOD 메서드 에서 JavaScript로 결과를 전달하려면 콜백을 사용하거나 이벤트를 내보낼 수 있다.(아래 설명 참조). RCT_EXPORT_METHOD 매크로를 사용하여 CalendarModule 네이티브 모듈에 대한 네이티브 메서드를 설정한다.
createCalendarEvent()를 호출하고 지금 이름과 위치 인수를 문자열로 사용한다. 인수유형 옵션이 곧 다루어진다.

createCalendarEvent() 메서드의 기능을 작성하기 전에 메소드에 콘솔 로그를 추가하여 React Native 응용 프로그램의 JavaScript에서 호출 되었음을 확인 할 수있다.
React의 RCTLog API를 사용한다. 파일 맨 위에 있는 헤더를 가져온 다음 로그 호출을 추가한다.

Synchronous Methods

RCT_EXPORT_BLOCKING_SYNCHORUS_METHOD를 사용하여 동기식 네이티브 메서드를 만들 수 있다.

이 메서드의 반환 유형은 개체 유형(ID) 이어야 하며 JSON 에서 직렬화 할 수 있어야 함. 이는 hook이 0 또는 JSON 값만 반환할 수 있음을 의미한다.(예: NSNumber,NSString,NSArray,NSDictionary)

현재 동기식 호출 방식은 성능 저하가 심하고 기본 모듈에 스레딩 관련 버그가 발생할 수 있으므로 동기식 메서드를 사용하지 않는것이 좋다.
또한 RCT_EXPORT_BLOCKING_SYNCHORUS_METHOD를 사용하도록 선택하면 앱이 더 이상 Google Chrome 디버거를 사용할 수 없다. 동기식 메서드에는 JS VM 이 애과 메모리를 공유해야 하기 때문이다.Google Chrome 디버거의 경우 React Native는 Google Chrome의 JS VM 내에서 실행되며 WebSockets를 통해 모바일 장치와 비동기식으로 통신한다.

Test What You Have Built

이제 iOS에서 기본 모듈의 기본 scaffolding 설정했음. 네이티브 모듈에 액세스하여 JavaScript에서 내보낸 메서드를 호출하여 테스트 한다.

응용 프로그램에서 네이티브 모듈의 createCalendarEvent() 메서드에 호출을 추가할 위치를 찾는다.
다음은 앱에 추가할 수 있는 NewModuleButton 구성요소의 예이다.
NewModuleButton's onPress() 기능 내에서 네이티브 모듈을 호출할 수 있다.

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

const NewModuleButton = () => {
  const onPress = () => {
    console.log('We will invoke the native module here!');
  };

  return (
    <Button
      title="Click to invoke your native module!"
      color="#841584"
      onPress={onPress}
    />
  );
};

export default NewModuleButton;

JavaScript에서 네이티브 모듈에 액세스 하려면 먼저 React Native 에서 모듈을 가져와야한다.

import {NativeModules} from "react-native';

그런다음 Native Modules에서 Calendar Module 기본 모듈에 액세스 할 수 있다.

const { CalendarModule } = NativeModules;

이제 CalendarModule 기본 모듈을 사용할 수 있게 되었으므로 기본 매서드 createCalendarEvent()를 호출 할 수 있다. 아래에는 새 모듈 버튼의 onPress() 매서드가 추가된다.

const onPress = () => {
  CalendarModule.createCalendarEvent('testName', 'testLocation');
};

마지막 단계는 최신 네이티브 코드(새 네이티브 모듈)를 사용할 수 있도록 React Native 앱을 재구성하는 것이다.

npx react-native run-ios

Building as You lterate

이 안내서를 살펴보고 기본 모듈에서 반복할 때, JavaScript에서 가장 최근에 변경한 내용에 액세스하려면 응용 프로그램의 기본 재구성을 수행해야한다. 이는 작성중인 코드가 응용 프로그램의 기본 부분 내에 있기 때문이다. React Native의 메트로 번들러는 JavaScript의 변경사항을 즉시 확인하고 JS 번들을 재구축 할 수 있지만 네이티브 코드에는 그렇게 하지 않는다. 따라서 최신 네이티브 변경 사항을 테스트 하려면 npx react-native run-ios 명령을 사용하여 재구성 해야 한다.

Recap

이제 JavaScript에서 기본 모듈에서 CreateCalendarEvent() 메서드를 호출할 수 있음.
function 에서 RCTLog를 사용 중이므로 앱에서 디버그 모드를 활성화 하고 Chrome 또는 모바일 앱 디버거 플리퍼의 JS 콘솔을 확인하여 네이티브 메서드가 호출 외고 있는지 확인할 수 있음.
네이티브 모듈 메서드를 호출할 때 마다 RCTLogInfo(@"%@", 이름, 위치), 메시지를 표시해야함

Beyound a Calendar Native Module

Better Mative Module Export

위와 같이 Native Module에서 분리하여 네이티브 모듈을 가져오는 것은 불편함.
네이티브 모듈의 소비자가 네이티브 모듈에 액세스 할 때마다 이 작업을 수행하지 않아도 되도록 하기 위해 모듈에 대한 JavaScript래퍼를 만들 수 있다. 다음 내용을 사용하여 NativeCalendarModule.js라는 새 JavaScript 파일을 만든다.

Argument Types

JavaScript 에서 네이티브 모듈 메서드가 호출되면 React Native는 인수를 JS개체에서 Objective-/Swift 개체 아날로그로 변함. 예를 들어, Objective-C Native Module 메서드가 NSNumber를 수락하는 경우 JS에서 메서드 number로 호출해야함. React Native가 변환을 처리한다. 아래는 네이티브 모듈 메서드에서 지원되는 인수 유형과 이러한 메서드가 매핑되는 목록이다.

ObJECTIVE-CJAVASCRIPT
NSStringstring, ?string
BOOLboolean
NSNumber?boolean
doublenumber
NSNumber?number
NSArrayArray, ?Array
NSArrayArray, ?Array
NSDictionaryObject, ?Object
RCTResponseSenderBlock Function (success)
RCTResponseSenderBlock, RCTResponseErrorBlockFunction (failure)
RCTPromiseResolveBlock, RCTPromiseRejectBlockPromise

iOS의 경우 RCTConver클래스에서 지원되는 인수 유형을 사용하여 네이티브 모듈 메서드를 작성할 수도 있음
RCTConvert 도우미 함수는 모두 JSON 값을 입력으로 수락하고 기본 Objective-C 유형 또는 클래스에 매핑

Exporting Constants

네이티브 모듈은 네이티브 메서드 constantsToExport()을 재 정의하여 상수를 내보낼 수 있음
constantsToExport()는 재정의되며, 다음과 같이 JavaScript에서 액세스 할 수 있는 기본 이벤트 이름 속성이 포함된 Dictionary을 반환 함

그런 다음 JS의 네이티브 모듈에서 getConstant()를 호출하여 상수에 액세스함

iOS의 경우 constantsToExport() 를 재정의할 경우 JavaScript 코드가 실행되기 전에 기본 스레드에서 모듈을 초기화해야하는지 여부를 React Native에 알려주기위해 +requiresMainQueueSetup을 구현해야함.
그렇지 않으면 +requiresMainQueueSetup 를 명시적으로 선택취소하지 않으면 나중에 모듈이 백그라운드 스레드에서 초기화 될 수 있다는 경고가 표시ㅇ됨
모듈에서 UIKit에 액세스 할 필요가 없는 경우 +requiresMainQueueSetup에 응답하여 주 대기열 설정을 NO로 지정해야함

Callbacks

Native modules는 고유한 인수(콜백)도 지원함. 콜백은 비동기 메서드를 위해 Object-C에서 JavaScript로 데이터를 전달하는 데 사용됨. 네이티브 측에서 JS를 비동기적으로 실행하는 데도 사용할 수 있음

iOS의 경우 RCTResponseSenderBlock 유형을 사용하여 콜백이 구현됨.
createCalendarEventMethod()에 콜백 매개 변수 myCallBack이 추가됨

그런 다음 기본 함수에서 콜백을 호출하여 배열에서 JavaScript에 전달할 결과를 제공할 수 있음.
RCTResponseSenderBlock은 JavaScript 콜백에 전달할 매개 변수 배열인 인수를 하나만 허용한다. 아래에서는 이전 콜에서 생성된 이벤트 ID를 전달한다.

그런다음 이렇게 JavaScript에서 엑세스 할 수 있다.

Native Module은 콜백을 한 번만 호출 하도록 되어있다. 그러나 콜백을 저장하고 나중에 호출 할 수 있다.
이 패턴은 대리인이 필요한 iOS API를 래핑하는데 종종 사용된다.(예 :RCT Alert Manager 참조). 콜백이 호출되지 않으면 일부 메모리가 유출된다.

콜백을 사용하여 오류를 처리하는 방법에는 두 가지가 있다. 첫 번째는 노드의 규칙을 따르고 콜백 배열에 전달된 첫 번째 인수를 오류 개체로 처리하는 것이다.

그 다음 JavaScript에서 첫 번째 인수를 확인하여 오류가 전달 되었는지 확인 할 수 있다.

또 다른 옵션은 onFailure와 onSucccess의 두 가지 콜백을 사용하는 것

JavaScript에 오류와 같은 개체를 전달하려면 RCTUtils.h의 RCTMakeError를 사용하면된다.
현재는 오류모양의 dictionary만 JavaScript로 전달되지만, React Native는 향후 실제 JavaScript Error 개체를 자동으로 생성하는 것을 목표로 한다.오류 콜백에 사요되고 NSError 개체를 허용하는 RCTResponseErrorBlock 인수도 제공할 수 있다.

Promise, Sending Events to JavaScript, Threading, Dependency Injection, Exporting Swift, Reserved Method Names 등과 같은 다른 개념들도 공식문서에 나와있다. 추후 다시 정리해 보아야겠다.

profile
잼나게 코딩하면서 살고 싶어요 ^O^/

0개의 댓글