iOS 13 beta 3 NFC的读写功能

苹果的NFC功能之前一直仅支持读取,并且读取格式为type1到5的NDEF。

Your app can read tags to give users more information about their physical environment and the real-world objects in it. Using Core NFC, you can read Near Field Communication (NFC) tags of types 1 through 5 that contain data in the NFC Data Exchange Format (NDEF). For example, your app might give users information about products they find in a store or exhibits they visit in a museum.

自从苹果出了XS以后又开放了Adding Support for Background Tag Reading(背景标签读取),但是也仅仅支持以下几种格式
在这里插入图片描述
听闻iOS13将要开放读写功能,这一福音不知道又有多少人兴奋的睡不着觉。
所谓前人栽树,后人纳凉,在使用过程中也遇到几个问题,首先把代码贴出来
1.首先初始化session

guard NFCNDEFReaderSession.readingAvailable else {
            let alerView = UIAlertController(
                title: "Scanning Not Supported",
                message: "This device doesn't support tag scanning.",
                preferredStyle: .alert
            )
            alerView.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alerView, animated: true, completion: nil)
            return
        }
        // 此处表示我要识别iso15693和iso14443两种NFC标签类型
        session = NFCTagReaderSession(pollingOption: [.iso15693, .iso14443], delegate: self)
        session?.alertMessage = "Hold your iPhone near the ISO15693 tag to begin transaction."
        session?.begin()

2.实现协议与协议方法

class ViewController: UIViewController, NFCTagReaderSessionDelegate
//    MARK: - Delegate
    @available(iOS 13.0, *)
    func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
        print("tagReaderSessionDidBecomeActive")
    }
    
    @available(iOS 13.0, *)
    func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
        print("tagReaderSession error:\(error)")
    }
    @available(iOS 13.0, *)
    func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
        print("tagReaderSession tags:\(tags)")
    }

重点在tagReaderSession方法中,因为我识别了两种标签类型,所以我做了判断,发送指令之前一定需要先建立连接

@available(iOS 13.0, *)
    func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
        print("tagReaderSession tags:\(tags)")
        var tag: NFCTag? = nil
        var type: Int = 0
        if case let .iso15693(fdTag) = tags.first {
            print("iso15693:\(self.string(from:  fdTag.identifier))")
            tag = tags.first
            type = 1
        }
        
        if case let .miFare(mifareTag) = tags.first {
            print("mifareTag:\(self.string(from:  mifareTag.identifier))")
            if mifareTag.mifareFamily == .ultralight {
                tag = tags.first
                type = 2
            }
        }
        
        if tag == nil {
            session.invalidate(errorMessage: "No valid tag found.")
            return
        }
        
        session.connect(to: tag!) { (error: Error?) in
            if error != nil {
                session.invalidate(errorMessage: "Connection error. Please try again.")
                return
            }
            print("connect tag:\(String(describing: tag))")
            
            if type == 1 {
                self.writeData(from: tag!)
            }else {
                self.readMifare(tag!)
            }
        }
    }

剩下的就是发送命令了,中间做了很多命令测试,例如15693的writeSingleBlock、readSingleBlock、getSystemInfo等,包括两条命令的顺序更换等,举个例子
写:

func writeData(from tag: NFCTag) {
        print("*********")
        guard case let .iso15693(one_five_six_nine_three_tag) = tag else {
            print("-----")
            return
        }
        let fastRead: [UInt8] = [0x00, 0x00, 0x00]
        DispatchQueue.global().async {
//            self.write15693(Data(fastRead), from: one_five_six_nine_three_tag)
            one_five_six_nine_three_tag.customCommand(requestFlags: [.highDataRate], customCommandCode: 0xCF, customRequestParameters: Data(fastRead)) { (responseData, error) in
                print("responseData:\(responseData),error:\(String(describing: error))")
            }
        }
    }

读(可以连续读取,因为标签需要两条命令之前间隔500ms所以我使用了延时):

func readMifare(_ tag: NFCTag) {
        guard case let .miFare(mifareTag) = tag else {
            return
        }
        DispatchQueue.global().async {
            //        let ledCommand: [UInt8] = [0x40, 0xc9, 0x02, 0x00, 0x00, 0x00, 0x00]
//            let first: [UInt8] = [0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00]
            let first: [UInt8] = [0x71, 0x07]
            mifareTag.sendMiFareCommand(commandPacket: Data(first)) { (responseData, error: Error?) in
                print("responseData:\([UInt8](responseData)), error:\(String(describing: error))")
//                DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
//                    let second: [UInt8] = [0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00]
//                    mifareTag.sendMiFareCommand(commandPacket: Data(second)) { (responseData, error: Error?) in
//                        print("temperature:\(self.string(from: responseData)), error:\(String(describing: error))")
//                        self.session?.invalidate()
//                    }
//                }
            }
        }
    }

中间遇到的问题:
1.
-[NFCTagReaderSession _connectTag:error:] Error Domain=NFCError Code=100 “Stack Error”
-[NFCTagReaderSession transceive:tagUpdate:error:]
解决方案:杀掉进程重新启动解决
2.15693错误
706 Error Domain=NFCError Code=2 “Missing required entitlement”
(Error Domain=NFCError Code=2 “Missing required entitlement” UserInfo={NSLocalizedDescription=Missing required entitlement}")
当报这个错误的时候已经成功地称为readSingleBlock函数从标签读取改变
经过大量查找问题可能是Xcode Beta 3版本问题。参考与跟踪:CoreNFC:使用NFCISO15693Tag协议发送自定义命令
今天Xcode Beta 4与iOS 13 Beta 4都出来了。是时候验证一把了

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页