[React Native] NFC 사용

Junseo Kim·2019년 10월 28일
1
post-custom-banner

NFC

expo에는 nfc 기능이 없기 때문에, 만약 expo를 사용중이라면, expo eject로 네이티브 앱으로 바꿔주어야한다.

아이폰은 애플계정이 필요하므로 안드로이드만 일단 해보겠다.(후에 추가할 것)

먼저 react-native-nfc-manager 를 설치해준다.

yarn add react-native-nfc-manager

react-native link react-native-nfc-manager

AndroidManifest.xml파일에 아래를 추가해준다.

<uses-feature android:name="android.hardware.nfc" android:required="false" />

코드는 아래와 같다.

import React, { Component } from 'react';
import { Platform, Text, View } from 'react-native';
import NfcManager, { Ndef, } from 'react-native-nfc-manager';

export default class App extends Component {
  state = {
    isReady: false,
  }
  
  constructor(props) {
    super(props);
    this.initNFC();
  }

initNFC = async () => {
  const isNFCSupport = await getIsNFCSupport();
  console.warn('isNFCSupport:', isNFCSupport);
  if (isNFCSupport == false) {
    return false;
  }

  const isNFCEnabled = await getIsNFCEnabled();
  console.warn('isNFCEnabled:', isNFCEnabled);
  if (isNFCEnabled == false) {
    return false;
  }

  this.setState(state => ({ ...state, isReady: true }));

  this.registerTagEvent();

  async function getIsNFCSupport() {
    try {
      await NfcManager.start();
      await NfcManager.isSupported();
      return true;

    } catch (e) {
      return false;
    }
  }

  async function getIsNFCEnabled() {
    const isIOS = (Platform.OS == 'ios');
    if (isIOS) {   //ios 버전인 경우
      return true;
    }

    try {
      const isNFCEnabled = await NfcManager.isEnabled();
      return isNFCEnabled;

    } catch (e) {
      return false;
    }
  }
}
//여기까지 NFC 리더 초기화 작업

  registerTagEvent = async () => {
    await NfcManager.registerTagEvent(
      this.onSuccessTagEvent,
      'Hold your device over the tag',
      {
        invalidateAfterFirstRead: true,
        isReaderModeEnabled: true,
        readerModeFlags: 0x1, // NfcAdapter.FLAG_READER_NFC_A
      }
    );
  }

  onSuccessTagEvent = async tag => {
    const parsed = tag.ndefMessage.map(decodeNdefRecord);
    parsed.forEach((item, i) => console.warn(`parsed[${i}]:`, item));

    function decodeNdefRecord(record) {
      if (Ndef.isType(record, Ndef.TNF_WELL_KNOWN, Ndef.RTD_TEXT)) {
        return ['text', Ndef.text.decodePayload(record.payload)];

      } else if (Ndef.isType(record, Ndef.TNF_WELL_KNOWN, Ndef.RTD_URI)) {
        return ['uri', Ndef.uri.decodePayload(record.payload)];

      } else {
        return ['unknown', '---'];
      }
    }
  }
  //여기까지 registerTagEvent()로 리스너를 등록하고, 값을 읽어옴
  
  
  componentWillUnmount() {
    NfcManager.unregisterTagEvent();
    NfcManager.stop();
  }
  //여기서 NfcManager를 종료

  render() {
    return (
      <View>
        <Text>isReady: {(this.state.isReady) ? 'TRUE' : 'false'}</Text>
      </View>
    );
  }
}
post-custom-banner

1개의 댓글

comment-user-thumbnail
2020년 1월 28일

안녕하세요 :) 포스트 보고 열심히 공부중인 개발자입니다. 질문이 있어 댓글 남기게 되었는데요, 해당 코드로 앱을 실행한 뒤 NFC 스티커를 인식하면 인식은 잘 되지만 NFC의 decoding 된 값이 warning으로 출력되지 않습니다 ㅠㅠ text나 uri 형식이 아니라면 unknown이라도 리턴해야할텐데.. 로그에도 찍히지 않아 여쭤봅니다!
혹시 registerTagEvent의 onSuccessTagEvent 함수가 실행되지 않는것인가요?!

답글 달기