-
[CoreNFC] NFC 읽고 시리얼 넘버(UID) 구하기/iOS 📱 2022. 8. 31. 17:46반응형
CoreNFC
이번에 사용 되는 Framework CoreNFC 입니다 !
어떤 일을 대신해줄 지 Apple 공식문서를 통해서 한번 알아보겠습니다 !
NFC tags를 발견하고, NDEF Data가 포함 된 메시지를 읽고, 쓰기 가능한 태그에 Data를 저장한다고합니다.
NFC 기술에 대한 정확한 지식은 없어도 우리가 개발을 하기 위해서는 NFC tag와 NDEF Data는 짚고 넘어가야 수월할 것 같네요 !!
이 전 블로그 포스팅과 비교하면 공식 문서에 대한 설명을 자세하게 다뤄볼 예정인데요 !제 iOS 개발에 저만의 멘토 두 분이 계신데,
항상 공식문서에 기반하여 남에게 설명할 수 있는 정확한 지식을 보유하고 계셔서 그 분들에에게 영향을 받았습니다.
NFC tag 또한 공식문서에 기반하여 얘기해볼게요 !
NFC 기술 및 표준화를 참고하면 ISO 15693, ISO 7816, felica (ISO 18092), miFare (ISO 14443A)
Core NFC 공식문서 Overview에 나와있듯이, NFC Tags는 Type1 ~ Type5로 나뉩니다.
- Type 1
- Type 2
- Mifare Ultra 포함
- Type 3
- Sony Felica
- Type 4
- ISO 7816
- Type 5
- ISO 15693 (Mifare Classic 4K, Mifare Classic 1K Mifare Classic Mini)
NFC는 Tag의 종류가 여러가지이며, 데이터 형식은 Type1 ~ 5 가 있는 것을 확인했어요
NFC 의 시리얼 넘버를 구하기위해서는 NFCTagReaderSession을 이용해야합니다.
그래서 이번 포스팅에서는 NFCTagReaderSession 에 대해서 설명드릴게요 !
NFCNDEFReaderSession에 대해서는 Apple에서 예제를 제공하고있습니다.
Apple Developer Forum 등 NFCNDEFReaderSession 에서는 uid를 못 가져올 지 검색을 해보았는데
NFC Tag의 uid에 접근하기위해서는 enum으로 정의 된 NFCTag object 에 접근헤야하는데
현재 NFCNDEFReaderSession 에서는 NFCTag object에 접근할 수 없었고,
Private API를 통해서 가져오는 방법은 Stackoverflow에서 확인할 수 있지만, 현재는 접근할 수 없었습니다 !! ㅜㅜ 혹여나 방법 아시는 분이 있다면 공유 부탁드려요info.plist에 key 추가해주기
NFC와 Core NFC에 대해서 간략하게 알아보았습니다 !!
아이폰에서 NFC 기능을 사용하기 위해서는 info.plist에 추가해줘야합니다 !
Target → Signing & Capabillities 에 NFC 추가하기
info.plist에 추가해주었다면 Project → Target → Signing & Capabillities 에서 NFC를 추가해줘야 합니다
NFCTagReaderSession init
NFCTagReaderSession을 통하여 태그하기 전에 생성자를 한번 살펴볼게요 !!!
PollingOption
pollingOption이란
iso14443(iso7816 & MiFare), iso15693, iso18092(Felica) 중 어떤 NFC 카드를 읽어올지에 대한 내용입니다.
근데 polling? 폴링이 뭐지 .. 처음 들어봤는데 궁금하네요
공식문서에서도 제 궁금증은 해결되지않았어요 !!
검색 중에 마이크로소프트에서 폴링해야 합니다 라는 구절로 폴링은 CS지식인 직감이 옵니다 !!위키백과 폴링 정의를 검색 해보죠 ㄱㄱ!!!
폴링(polling)이란 하나의 장치(또는 프로그램)이 충돌 회피 또는 동기화 처리 등을 목적으로 다른 장치(또는 프로그램)의 상태를 주기적으로 검사하여 일정한 조건을 만족할 때 송수신 등의 자료처리를 하는 방식을 말한다."
출처: https://ko.wikipedia.org/wiki/폴링_(컴퓨터_과학) [위키백과]
아 ... 여러분들 느낌 오셨나요 ? NFC 스캔 기본 60초 시간제한이 왜 생긴지 알거같습니다.
일정한 주기로 polingOption으로 할당한 NFC 카드가 태깅 됐는지 주기적으로 검사(polling)를 하는 것을 뜻하네요.
delegate, queue
delegate는 iOS 개발을 하다보면 가장 익숙한 패턴이죠 !!
Protocol을 정의하여 NFCTagReaderSession의 이벤트 발생 시 대신 처리할 곳을 찾고있네요
queue는 어떤 스레드에서 일을 할지 명시적으로 정해주는 부분이네요 기본 값이 nil입니다
nil인 경우 serial dispatch queue, 즉 main 에서 작동합니다.
Hello NFC !
NFC Scanning 버튼을 먼저 만들어볼려고합니다 !
private func addNFCTagButton() { let button = UIButton(frame: CGRect(x: 0, y: 0, width: 300, height: 80)) button.layer.borderColor = UIColor.white.cgColor button.layer.borderWidth = 1 button.setTitle("Scan Start", for: .normal) button.center = CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height - button.frame.height - 20) button.addTarget(self, action: #selector(startScanning), for: .touchUpInside) self.view.addSubview(button) }
button을 누르면 (touchUpInside) 발생시킬 이벤트를 만들었습니다.
@objc func startScanning() { let session = NFCTagReaderSession(pollingOption: .iso14443, delegate: self, queue: DispatchQueue.main) session?.alertMessage = "NFC 카드를 태깅해주세요" session?.begin() }
uid를 구한 후에 UILabel에 보여주도록할게요
class ViewController: UIViewController { private var label = UILabel() // Scan 이후에 접근하기 위해 프로퍼티로 선언 . . . . . private func addUIDLabel() { label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 40)) label.center = CGPoint(x: self.view.frame.width / 2, y: 150) self.view.addSubview(label) } }
위에서 생성자에서 설명한 것처럼 delegate에 대한 구현부를 작성해줍니다.
extension ViewController: NFCTagReaderSessionDelegate { //.begin() 이후 NFCTag ReaderSession이 실행되었을 때 호출 func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) { } // NFC Tag가 detect되었을 때 호출 func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) { let tag = tags.first! if case let NFCTag.miFare(mifareTag) = tag { session.connect(to: tag) { error in // 폼나게 작성해보기 ㅋㅋㅋ let UID = mifareTag.identifier.map { String(format: "%.2hhx", $0)}.joined() print("UID \(UID)") let tagUIDData = mifareTag.identifier var byteData: [UInt8] = [] tagUIDData.withUnsafeBytes { byteData.append(contentsOf: $0) } var uidString = "" for byte in byteData { let decimalNumber = String(byte, radix: 16) if decimalNumber.count == 1 { uidString.append("0") } uidString.append(decimalNumber) } session.alertMessage = "NFC UID 확인 !!" session.invalidate() // session.connect 내부 DispatchQueue.main.async { self.label.text = uidString } } //session.invalidate() session.connect 외부에서 호출 시에 Tag Complete 화면이 나오지않습니다 주석 풀어가면서 확인해보세요 ! } } // error라고 적혀있지만, 세션이 종료 될 때 호출 func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) { } }
이상 NFC tag의 UID 구하기입니다 .!!
예제 소스코드는 Github에서도 확인 가능합니다 !
https://github.com/kangddong/Blogexample/tree/main/BlogNFCTest/BlogNFCTest
' > iOS 📱' 카테고리의 다른 글
[iOS] UITableView (테이블뷰) 사용해보기 (0) 2022.12.27 [iOS] SF Symbol 사용하기 (0) 2022.11.28 [Firebase] Crashlytics 에서 .dSYM 파일 수동 추가하기 (0) 2022.08.25 로컬라이징(Localization, Localizable) 적용하기 / info.plist (0) 2022.08.21 [iOS] 화면 스크린샷 방지 기능 개발에 대한 회고 (0) 2022.07.06