투케이2K

158. (TWOK/UTIL) [Ios/Swift] C_Nfc_Card_Module : NFC 세션 활성 및 NDEF 메시지 확인 클래스 본문

투케이2K 유틸파일

158. (TWOK/UTIL) [Ios/Swift] C_Nfc_Card_Module : NFC 세션 활성 및 NDEF 메시지 확인 클래스

투케이2K 2025. 1. 25. 18:11

[설 명]

프로그램 : Ios / Swift

설 명 : [Ios/Swift] C_Nfc_Card_Module : NFC 세션 활성 및 NDEF 메시지 확인 클래스

 

[소스 코드]

import Foundation
import UIKit
import CoreNFC

class C_Nfc_Card_Module: NSObject, NFCNDEFReaderSessionDelegate {
    
    

    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 1. NFC 카드 읽기 및 쓰기 관련 모듈 클래스 (NFC 기능은 iOS 11 이상에서 지원됩니다)
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 2. Entitlements 설정 :
     *
     * Xcode에서 프로젝트 > Signing & Capabilities > + Capability > Near Field Communication Tag Reading 추가
     *
     * >> 요소에서 Near Field Communication Tag Reader Session Formats 가 정상적으로 활성화 된 것 확인 필요
     * >> 요소 추가에서 NDEF , TAG 값 2개 추가
     * >> 참고 사이트 : https://blog.naver.com/kkh0977/223729651712
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 3. Info.plist: NFC 사용 권한 요청 메시지 추가
     *
     * <key>Privacy - NFC Scan Usage Description</key>
     * <string>이 앱은 NFC를 사용하여 카드 정보를 읽고, 쓸수있습니다.</string>
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 4. 필요 import :
     *
     * import UIKit
     * import CoreNFC
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 5. 필요 delegate 설정 :
     *
     * NFCNDEFReaderSessionDelegate
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */

    




    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * //  TODO [빠른 로직 찾기 : 주석 로직 찾기]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : startNfcScan : NFC 스캔 동작 수행
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : stopNfcScan : NFC 스캔 동작 종료
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     *
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [전역 변수 선언]
    // -----------------------------------------------------------------------------------------
    public static let ACTIVITY_NAME = "C_Nfc_Card_Module"
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : startNfcScan : NFC 스캔 동작 수행
    // -----------------------------------------------------------------------------------------
    // TODO [호출 방법 소스 코드]
    // -----------------------------------------------------------------------------------------
    /*
     
     DispatchQueue.main.async { // [비동기 요청]
         
         C_Nfc_Card_Module().startNfcScan(type: 0){(result) in
             
             S_Log._D_(description: "NFC 스캔 결과 확인", data: ["\(result)"])
             
         }
         
     }
     
    */
    // -----------------------------------------------------------------------------------------
    /*
     *
     * -----------------------------------------------------------------------------------------
     * TODO [설명] : NFC TAG , NDEF 메시지 스캔 메소드
     *
     * 1) 사전) Xcode 에서 NFC 기능 사용 설정 필요 : https://blog.naver.com/kkh0977/223729651712
     * 2) 사전) NFCNDEFReaderSessionDelegate 클래스 상속 필요
     * -----------------------------------------------------------------------------------------
     * TODO [Input] : 인풋 파라미터
     *
     * @param type : NFC 스캔 동작 타입 (0 == TAG / 1 == NDEF 메시지)
     * -----------------------------------------------------------------------------------------
     * TODO [Return] : 리턴 데이터
     *
     * @return : NFC 실행 성공 및 실패 값 Ture, False 리턴
     * -----------------------------------------------------------------------------------------

     * -----------------------------------------------------------------------------------------
     * TODO [History] : 이력 정리 [create , update , delete]
     *
     * 1) KwonGiHwan : create : 2025-01-19 : 최초 생성 수행
     * -----------------------------------------------------------------------------------------
     *
     * */
    
    public static var nfcSession: NFCNDEFReaderSession? = nil // [NFC 스캔 객체]
    var nfcScanResult = false // [NFC 스캔 데이터]
    var scan_log = "" // [스캔 동작 로직 로그]
    public static var NFC_SCAN_TYPE = -1 // [NFC 스캔 타입]
    private let nfcScanOperationQueue = OperationQueue() // [작업 큐]
    
    func startNfcScan(type: Int, callback: @escaping (Bool) -> ()) {
        S_Log._D_(description: "NFC 스캔 수행 실시", data: nil)
        
        
        // [변수 값 초기화]
        C_Nfc_Card_Module.nfcSession = nil
        self.nfcScanResult = false
        C_Nfc_Card_Module.NFC_SCAN_TYPE = -1
        self.scan_log = ""
        
        
        // [작업 큐에 추가]
        self.nfcScanOperationQueue.isSuspended = true
        let block = { callback(self.nfcScanResult) }
        self.nfcScanOperationQueue.addOperation(block)
        
        
        DispatchQueue.main.async {
         
            // [NFC 사용 가능 기기 상태 확인] : NFCNDEFReaderSession.readingAvailable
            C_StateCheck().getNfcState(){(result) in
                S_Log._D_(description: "NFC 권한 부여 및 사용 가능 상태 확인", data: ["\(result)"])
                
                if result == true {
                    
                    // [스캔 타입 전역 변수 삽입]
                    C_Nfc_Card_Module.NFC_SCAN_TYPE = type
                    
                    
                    // [방어 로직 : 스캔 타입 값 확인]
                    if C_Nfc_Card_Module.NFC_SCAN_TYPE == 0 || C_Nfc_Card_Module.NFC_SCAN_TYPE == 1 {
                        
                        // ---------------------------------------------
                        // MARK: [NFC 세션 초기화 및 스캔 동작 수행]
                        // ---------------------------------------------
                        C_Nfc_Card_Module.nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
                        C_Nfc_Card_Module.nfcSession?.alertMessage = "NFC 태그에 기기를 가까이 대주세요."
                        C_Nfc_Card_Module.nfcSession?.begin()
                        // ---------------------------------------------
                        
                        
                        // ---------------------------------------------
                        // MARK: [작업 성공 처리]
                        // ---------------------------------------------
                        // NFCNDEFReaderSessionDelegate : 딜레게이트에서 실시간 스캔 데이터 확인
                        // ---------------------------------------------
                        // NFCNDEFTag / NFCNDEFMessage
                        // ---------------------------------------------
                        self.scan_log = "[Success] :: Nfc Scan Start"
                        S_Log._W_(description: "NFC 스캔 동작 성공", data: ["\(self.scan_log)"])
                        
                        self.nfcScanResult = true
                        self.nfcScanOperationQueue.isSuspended = false
                        // ---------------------------------------------
                        
                    }
                    else {
                        
                        // [작업 종료 처리]
                        self.scan_log = "[Error] :: Nfc Scan Type Check Error"
                        S_Log._E_(description: "NFC 스캔 동작 에러", data: ["\(self.scan_log)"])
                        
                        self.nfcScanOperationQueue.isSuspended = false
                        
                    }
                }
                else {
                    
                    // [작업 종료 처리]
                    self.scan_log = "[Error] :: C_StateCheck getNfcState False"
                    S_Log._E_(description: "NFC 스캔 동작 에러", data: ["\(self.scan_log)"])
                    
                    self.nfcScanOperationQueue.isSuspended = false
                    
                }
            }
            
        }
        
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : stopNfcScan : NFC 스캔 동작 종료
    // -----------------------------------------------------------------------------------------
    // TODO [호출 방법 소스 코드]
    // -----------------------------------------------------------------------------------------
    /*
     
     DispatchQueue.main.async { // [비동기 요청]
         
         C_Nfc_Card_Module().stopNfcScan()
         
     }
     
    */
    // -----------------------------------------------------------------------------------------
    /*
     *
     * -----------------------------------------------------------------------------------------
     * TODO [설명] : NFC TAG , NDEF 메시지 스캔 종료 메소드
     *
     * 1) 사전) Xcode 에서 NFC 기능 사용 설정 필요 : https://blog.naver.com/kkh0977/223729651712
     * 2) 사전) NFCNDEFReaderSessionDelegate 클래스 상속 필요
     * -----------------------------------------------------------------------------------------
     * TODO [History] : 이력 정리 [create , update , delete]
     *
     * 1) KwonGiHwan : create : 2025-01-19 : 최초 생성 수행
     * -----------------------------------------------------------------------------------------
     *
     * */
    
    func stopNfcScan() {
        S_Log._D_(description: "NFC 스캔 종료 실시", data: nil)
        
        DispatchQueue.main.async {
         
            if C_Nfc_Card_Module.nfcSession != nil {
             
                C_Nfc_Card_Module.nfcSession?.invalidate()
                C_Nfc_Card_Module.nfcSession = nil
                
            }
            
        }
        
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [NFCNDEFReaderSessionDelegate] : NFC NFCNDEFMessage 읽기 성공 시 호출
    // -----------------------------------------------------------------------------------------
    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        
        if messages != nil && messages.count > 0 {

            for message in messages {
                for record in message.records {
                    if let payload = String(data: record.payload, encoding: .utf8) {
                        S_Log._W_(description: "\(C_Nfc_Card_Module.ACTIVITY_NAME) :: didDetectNDEFs :: NFC 태그 내용 확인", data: ["payload :: \(payload)"])
                    } else {
                        S_Log._E_(description: "\(C_Nfc_Card_Module.ACTIVITY_NAME) :: didDetectNDEFs :: NFC 태그 데이터를 읽을 수 없습니다", data: nil)
                    }
                }
            }
            
        }
        else {
            S_Log._E_(description: "\(C_Nfc_Card_Module.ACTIVITY_NAME) :: didDetectNDEFs :: NFCNDEFMessage 가 없습니다", data: nil)
        }

    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [NFCNDEFReaderSessionDelegate] : NFC 세션 종료 시 호출
    // -----------------------------------------------------------------------------------------
    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        if let nfcError = error as? NFCReaderError {
            S_Log._E_(description: "\(C_Nfc_Card_Module.ACTIVITY_NAME) :: didInvalidateWithError :: NFC 세션 종료 확인", data: ["NFCReaderError :: \(nfcError.localizedDescription)"])
        }
        else {
            S_Log._E_(description: "\(C_Nfc_Card_Module.ACTIVITY_NAME) :: didInvalidateWithError :: NFC 세션 종료 확인", data: ["Status :: readerSession End"])
        }
        
        // [NFC 스캔 종료 및 객체 초기화]
        self.stopNfcScan()
        
    }
    
    
} // [클래스 종료]
 
 

 

반응형
Comments