목차
I. What is NFC?
II. nfc_manager 패키지
III. in Flutter
IV. in Android
V. in iOS
VI. 앱에서 NFC 활용 방법
VII. 요약
VIII. reference
I. What is NFC?
최근 애플페이 서비스를 한국에서도 시행할 것이라는 뉴스를 봤다. 애플페이는 NFC를 이용해서 결제가 이루어진다. 따라서 스마트폰에서 NFC기능을 지원해야 하는데 Apple은 iPhone6 이후 모든 스마트폰(태블릿에는 안들어가 있는 듯하다)에 NFC기능을 집어 넣었다. 그렇다면 꽤 오래전부터 상용화된 기능인 NFC는 무엇일까?
NFC는 "Near Field Communication"의 약자로 스마트폰과 같은 전자기기가 다른 전자기기와 근거리 무선통신을 하기 위해 개발된 기술이다. RFID와 같이 근거리에서 무선통신이 목적이지만 둘은 약간의 차이가 있다. NFC의 기술적인 내용은 본인도 모르기 때문에 패스한다. 개발자 입장에서 중요한 것은 NFC를 앱 개발에서 활용하기 위해서 알아야 할 내용이 무엇인지 확인하는 것이다.
NFC를 이용해 정보를 주고 받을 때 그 정보의 형식은 NDEF format으로 표준화되어있다. 마치 서버에서 Json형식으로 Data를 받듯이 NFC에서는 NDEF형식으로 Data를 받는다. NDEF은 구체적으로 NDEF Message가 있고 그안에 여러 Record들이 있는 형식이다. 각 Record에서 Payload안에 우리가 원하는 데이터가 들어있고 Header에는 Payload에 관한 정보를 담고 있다. 사실 개발을 할 때에는 Record에 원하는 정보를 쓰고 읽는다는 정도까지만 알고 있으면 된다!
본인은 2021년도 8월경 출시한 "아인스 필터"라는 앱을 만들면서 NFC 기능을 이용해 개발하였고 군복무로 인해 귀중한 경험이 잊혀질까 두려워 그 경험을 개인 블로그에 남겨본다.
II. nfc_manager 패키지
pub.dev에서 nfc_manager 3.1.0 패키지를 이용해서 개발하였다. 아마 android와 ios의 native에서 nfc를 다루는 방법이 있을 텐데 배움이 부족하여 패키지를 이용하였다. 언젠가는 android와 ios를 마스터하고 method channel을 이용하여 패키지에 의존하지 않고 개발을 할 것이다.
https://pub.dev/packages/nfc_manager
Readme부분을 잘 읽고 setup을 수행해야한다.
현재는 3.2.0 버전까지 나와서 더 편하게 사용할 수 있을 것 같다. 전에는 likes도 적고 popularity도 낮아서 후술하는 다른 이유가 없었다면 이 패키지를 사용하지 않았을 것 같다. 한창 “아인스 필터” 앱을 개발하던 21년도 7월 당시 NFC 관련 정보가 매우 적었고 특히 한글 정보는 다른 프레임워크 또한 관련 정보가 거의 없다시피 했는데, 기적적으로 NFC 기술을 활용해 Flutter로 만들어진 앱을 블로그에서 보았고 그 블로그에서 이 패키지를 사용하였기에 나 또한 안심하고 사용하였다.
https://muhly.tistory.com/68#comment16945474
🙏🙏🙏🙏너무 감사합니다!
III. in Flutter
NFC에 데이터를 읽는 read 과정과 데이터를 저장하는 write 과정이 있는데, write과정은 여기서 짧게 살펴보고 뒤에서 주로 read과정을 살펴볼 것이다.
앱에서 NFC 를 read 하기 위한 버튼을 사용자가 누른 순간부터 android와 iOS의 UI/UX 가 달라지기 때문에 크로스 플랫폼으로서 Flutter가 장점을 발휘할 부분은 많지 않다. 따라서 NFC스티커를 read 하는 동안에는 android 와 iOS가 다르게 작동하지만 read가 끝난 후 데이터를 처리하는 과정은 두 OS가 공통되기 때문에 데이터를 다루는 공통된 함수가 존재한다.
_handleTag라는 함수가 공통되는 과정으로서 뒤에 android, iOS 코드에서 언급되므로 여기서 확인을 한번 하고 간다.
NFC 에 write하는 코드에서 또한 이 함수를 사용한다.
내가 만든 앱에서는 NFC스티커 속에 존재하는 고유 serial number 자체를 이용한다. _handleTag는 16진법으로 표현된 serial number를 String 타입의 id로 저장해서 반환해 주는 함수다.
NFC write를 하는 과정은 android 쪽만 확인하고 넘어갈 것이다. android만 확인하는 이유는 설명하기 귀찮다. (이유가 귀찮은게 아니다.)
32번째 줄부터 빠르게 확인하고 넘어가자. 위에서 언급했던 NDEF Message 에 Uri를 담은 Record 를 넣어주는 모습이다. 다른 Record 는 더 넣지 않았다.
IV. in Android
안드로이드에서는 NFC를 Wi-Fi와 같이 끄고 킬 수 있다. 따라서 android에서 NFC를 이용할 수 없는 상황은 두가지 경우가 있을 수 있는데 스마트기기에서 NFC기능 자체를 지원하지 않는 경우이거나 사용자가 NFC기능을 끈 경우가 있다. 불행인지 다행인지 NFC기능 자체를 지원하지 않는 스마트기기는 아직 못구해서 테스트하지 못하였고 NFC기능이 꺼져있는 경우 코드가 잘 실행되고 있다.
초기 세팅을 위한 코드이다.
nfc_manager패키지에서 제공해주는 NfcManager.instance.isAvailable() 함수를 통해 NFC기능 여부를 체크할 수 있다.
만약에 NFC기능이 꺼져 있다면 오류 메시지와 함께 설정과 확인 버튼이 있고, 설정 버튼을 누른다면 NFC를 활성화할 수 있도록 디바이스 설정으로 넘어간다. 이때 app_settings 라는 패키지를 썼는데 사용법도 간단하고 여러모로 쓸모가 많았던 패키지이다.
https://pub.dev/packages/app_settings
android에서는 스마트폰이 NFC를 스캔여부를 팝업 메시지 정도로만 사용자에게 알려주고 따로 UI/UX 로 표현되지 않기 때문에 사용자 입장에서는 NFC 스캔이 잘 되고 있는지 실패했는지를 확인하기 번거롭다. 따라서 이 앱에서는 NFC 를 스캔하는 동안 Alert 메시지를 띄워준다. 스캔에 시작하면 스캔중이라는 메시지를 띄어주고 만약 스캔에 실패하거나 데이터를 읽지 못한다면 띄어준 alert 메시지에서 에러를 출력한다.
NFC 태그를 인식하면 alert메시지가 바뀌고 확인을 누르면 NFC로부터 얻은 값을 반환하여 화면을 업데이트한다.
V. in iOS
iOS에서 굉장히 많이 삽질을 했던 기억이 난다. 그동안 Flutter와 둘이서만 함께했기에 내게는 iOS가 너무 어려웠고 복잡했다. 특히 enrollment 를 비롯해서 Xcode 에서 세팅이 말도 안되게 어려웠고 NFC관련 세팅 정보가 너무 없어서 스트레스를 받았었다. 사실 다시하라고 하면 Xcode 세팅 때문에 또 삽질할 것 같다. 다행히도 내 옆에 Line개발자(당시에는 컴붕이 대학생)가 든든하게 있었고 그친구와 함께 문제를 해결했다. wizi최고~!
native코드를 뜯어보지는 않았지만, android와 비교해 보았을 때 ios에서는 NFC를 읽기 위해서 나오는 "스캔 준비 완료"라 써져 있는 ui가 기본적으로 제공되는거 같다. 이는 장점이자 단점이 되었는데, 확실히 iOS라 UI가 상당히 깔끔하고 이쁘다. 하지만 이는 개발자 입장에서는 예상하지 못한 변수를 야기하기 때문에 보이는 바와 같이 iOS에서 NFC를 인식하는 동안에는 Navigator에 새로운 창을 넣고 사용자가 확인 또는 취소 텍스트 버튼을 눌러서 다음 단계로 넘어갈 수 있도록 하였다.
지금 보니 android에 비해 코드가 더 간단해 보이는데, 사실 시간이나 노력은 iOS에서 훨씬 많이 들었다. 특히 pollingOptions 부분은 왜 저렇게 해야하는지 아직 모르겠다. 패키지에 Readme 부분이 빈약해서 Example 보고 배워서 사용하려니 애를 먹었는데, 다시한번 wizi 최고!
NFC read가 끝난 후, 즉 iOS 에서 제공해준 UI가 끝난 후 Flutter가 NFC 스캔이 끝났다는 사실을 알고 UI를 업데이트하거나 다음 단계로 넘어가기가 번거롭다. 그래서 해결책으로 Navigator 로 새로운 페이지를 push하고 iOS에서 제공해준 NFC스캔 UI가 끝난 후 사용자가 확인 또는 취소 텍스트 버튼을 눌러서 그 페이지가 pop 되었을 때 UI를 업데이트하였다.
VI. 앱에서 NFC 활용 방법
외주를 맡겨준 회사에서 NFC스티커를 제품에 붙여서 소비자에게 배송했다. 제품을 배송 받은 고객들이 "아인스 필터" 앱을 이용해서 NFC스티커를 스캔하고 NFC스티커 고유의 serial number를 id로 활용하여 앱과 서버에서 제품을 등록하였다. 또한 URI를 write한 NFC스티커를 배송해서 고객께서 "아인스 필터" 앱이 없는 스마트기기로 NFC를 read한 경우 firebase dynamic link 를 통해 Google Play나 앱스토어에 등록된 "아인스 필터" 설치 페이지로 연결될 수 있도록 하였다.
만약 NFC 에 고객명이 담긴 string 값을 집어넣어서 제품을 등록할때 고객명을 활용해서 감사인사를 하거나 "나의 G9plus" 대신 "쿨쿨라이언의 G9plus" 이런 식으로 UI/UX를 구성하였다면 좀 더 감성 넘치는 서비스를 제공할 수 있었을 것 같다.
다른 여러 앱들의 상황에 따라서 NFC를 활용할 수 있는 아이디어를 내자면 무수하게 쏟아질 것이다.
VII. 요약
1. NFC는 NDEF 형식으로 데이터를 주고받는데, 이는 NDEF Message 속에 여러 Record들이 있고 Record에 데이터를 저장하는 방식이다.
2. Android는 NFC기능을 키고 끌 수 있고 iOS는 항상 NFC기능을 사용할 수 있는 상태이다.
3. Android는 NFC를 스캔할 때에 따로 UI/UX가 없기 때문에 개발자가 직접 사용자에게 스캔하고 있음을 보여주어야 할 필요가 있다. 하지만 iOS는 자체적으로 제공하는 UI/UX가 있고 Flutter 특성상 스캔에 성공하거나 실패했을 때에 바로 다음 과정으로 프로세스 처리가 이어질 수 없기 때문에 이를 해결하는 방법이 필요하다.
VIII. reference
이미지 출처
https://kr.freepik.com/premium-vector/contactless-wireless-payment-method-for-the-nfc-logo-nfc-technology-will-help-you-pay-less_23099915.htm
https://smartits.tistory.com/206
'프로그래밍 > Flutter' 카테고리의 다른 글
[Flutter] TextFormField의 suffixIcon에 IconButton 사용시 문제점과 해결방안 - 비밀번호 가리기 (1) | 2021.04.01 |
---|