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