From 763c12f86e9a0d91b7707abdee20d7c4edfc5e01 Mon Sep 17 00:00:00 2001 From: denggaofeng <1139968554@qq.com> Date: Fri, 23 Jan 2026 13:56:08 +0800 Subject: [PATCH] =?UTF-8?q?ios=E7=BB=91=E5=AE=9A=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NfcLock.Ios.Binding/ApiDefinition.cs | 27 +- .../UserInterfaceState.xcuserstate | Bin 16015 -> 18101 bytes .../NfcLockFramework/NfcLockFramework.swift | 243 +++++++++++------- 3 files changed, 168 insertions(+), 102 deletions(-) diff --git a/NfcLock.Ios.Binding/ApiDefinition.cs b/NfcLock.Ios.Binding/ApiDefinition.cs index 19307c4..8089a7c 100644 --- a/NfcLock.Ios.Binding/ApiDefinition.cs +++ b/NfcLock.Ios.Binding/ApiDefinition.cs @@ -7,39 +7,48 @@ namespace NfcLock.Ios.Binding [DisableDefaultCtor] interface NFCManager { - // -(void)startScan; + // +(void)startScan; + [Static] [Export ("startScan")] void StartScan (); - // -(void)endScan; + // +(void)endScan; + [Static] [Export ("endScan")] void EndScan (); - // -(void)endScanWithErrorMessage:(NSString * _Nonnull)errorMessage; + // +(void)endScanWithErrorMessage:(NSString * _Nonnull)errorMessage; + [Static] [Export ("endScanWithErrorMessage:")] void EndScanWithErrorMessage (string errorMessage); - // -(void)setLoopCbWithCb:(id)cb; + // +(void)setLoopCbWithCb:(id)cb; + [Static] [Export ("setLoopCbWithCb:")] void SetLoopCbWithCb (NSObject cb); - // -(void)setFinishedCbWithCb:(void (^ _Nonnull)(void))cb; + // +(void)setFinishedCbWithCb:(void (^ _Nonnull)(void))cb; + [Static] [Export ("setFinishedCbWithCb:")] void SetFinishedCbWithCb (Action cb); - // -(void)setChargingCbWithCb:(void (^ _Nonnull)(NSString * _Nonnull, int))cb; + // +(void)setChargingCbWithCb:(void (^ _Nonnull)(NSString * _Nonnull, int))cb; + [Static] [Export ("setChargingCbWithCb:")] void SetChargingCbWithCb (Action cb); - // -(void)setControllingCbWithCb:(void (^ _Nonnull)(NSString * _Nonnull, int))cb; + // +(void)setControllingCbWithCb:(void (^ _Nonnull)(NSString * _Nonnull, int))cb; + [Static] [Export ("setControllingCbWithCb:")] void SetControllingCbWithCb (Action cb); - // -(void)lockWithPassword:(NSString * _Nonnull)password; + // +(void)lockWithPassword:(NSString * _Nonnull)password; + [Static] [Export ("lockWithPassword:")] void LockWithPassword (string password); - // -(void)unlockWithPassword:(NSString * _Nonnull)password; + // +(void)unlockWithPassword:(NSString * _Nonnull)password; + [Static] [Export ("unlockWithPassword:")] void UnlockWithPassword (string password); } diff --git a/NfcLock.Ios.Binding/NfcLockFramework/NfcLockFramework.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate b/NfcLock.Ios.Binding/NfcLockFramework/NfcLockFramework.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate index 88eb74d3b7d3e223a146e8d6cf0e2e174dc2a6e7..3da535e4ec055599225a18e5ebb3195f1d9a5dd4 100644 GIT binary patch delta 8172 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 T0fg9J1$)S)`i6$z)NlU}SB2R% delta 6846 zcmZvA34Baf`~P{)xice~WR_$ynKg4WlbOlv6DA0?#2%7ZA}T0?AhkA$z3rS!X{jo1 z7hR|%cBP25YAcGAE~u)#w%Tebs;c;%NyPu{|9vx`naO?bIp(EBD32jC@(Ju5g+Kcw1Z_#(?d-NN+g07-# z=sLQAen&UaEp!{*K@ZS<^a%Zf9zzsFg9^0h9wdShEWkqw*ueu{2to+bp$RmHR?rRd zpgZJ44|oxJhM@ok!XPMu!SFJ?3R7S@yaRLKefR)AhJ{cLi(oMG7S9Kz{13wOkwa5m1txwtd#g1h1uaZmgb9)gGBV*D~5hR5Kscp{#J1w0MU z#&hso{3)J~7vQh(HoP70z&r6S{59T<_u#$w8@vzi#|Q9t_%J?#PvbNAEWU&v&vj_R zL{8#}ff$L2IEa&^5*P82G?GD@kXEEM$s#!EOrm&92(o=fJe zoR{-)ey%>(kZZ@a=Q?m%Tt}`Gm&<>8DD_9Xv35)WBiwN(x65jT==m%s*(NmT&_ZgL8a9+$lNza+vni!rcA8URLJE_YIr6+#MznDq^V?@ zm^i6UtejcSvm40@u|rgAJguJiPL#NF?kYgpLOxGMS1K&Ny6*5T&KiSvCfDq62;4jThLb#%f3WgX%pJC z0&PRv=?k>EI8D)`?QXPZA#HXTjYZ?oH)!9Bxp|o-C500z*u})dHGUmH)eC8h+7$=U zp}x6!Ib+HS2MjN&Sy+hM3{0CB2{5BAL|9A7-5cw*6@yt2ZwqJAoMo1y_@h72hx$s0YqxU5HU(YPb% z4|JCSbC1=lKg9;gPOl17i00I~@)vs8J2x*Yl6_rR9#){g(Zv50i0b47ql!841U&_W zlmLK%00$C~f()G&tJE*c`_Mevj}D;SXs(zV*SMh^?Wu$qhy?}hPJ7Z`wAm3*Lmb;3 z4;o15l{KhnWLfdx;-ZrL8qGAH_Mk6{*-`qa8mmADdhtx0g;an+JQZhC*KRhU(~v+5 zSa4p95G20t(Bv9f2b2soH3C!~T4+`SoP#*AS4^1EdhlogLCDlID zu#L{I)#w9%KUI929^KnKTh4e_SXMl0WCaA!#Q%NkFw>F-^`Swp2!->?N{UAgp@p=6 zKUINvHc%k0(MUB7p;2#kYP;g$MUnVcLSx7ft2GYN6kZVTYJAX4OipOfz6Gi-hn92@ zZSjm6&>A`-?-FPOZP8I^4;>(j7SX{hdxp@Vw0H?hfo#ZOug)li#?qJRF!mZQev%Lr zk0o@m^n$*~TM50P54=Q2(2;ahCG>;-P)JA9&uF>WR+}9dg7%cdQ2GjO_6rPy;V=S5 z!YJm_Xm|xm7*b_02F9{Ia3EzA{AnV*}-QlSDW#Ot~)`AcCP(yoAIupCyvO86XB!D{#d z*1%dCrj!bFGMz%-pi}8I`X+sA1yrFF8Ijs zy-hrG)Ak+uSk z!O!#^I;#SHffMvyDvCj4mIKbh`N++4@GG57=deNs7g-^jOKrV}7mqBeVN_A6_{6K{ z;TqgT+Df<%H{f^r9(|vFPzkr-Hr$~f(vRrJ;&EfR9z0+M{RI!jS>9yJyxKTDf`59j zIOS)xsenhU1i}-x<|$jV#hVQC#9bzXpTja{1(skbolh71hZXsQM-3lT+P98(*+nCV zlnoU%W*<>vmDt~$NGh;e>}$5<$JbQdXFg*sHnL`b6R{5Kv4K|7MRYM;vIv{788p~J zm(tH!m^M&%&+MYXHKnbfTk(*gHUIU>E}SrGOj*vTK}F&=v#zeeU_sb?u!R7AaFn2 z9~aUs^h>(65+@=DE@FNv=~tp!9SqxAmi9-Hzq<2> zV;mljybBjnx9a&Juj1FA8yTiwQ+G`U;>i&+r{Fi}Zu(8FnRb?#_)Yxwf2o|wRL-J% zn99A>CT6M)JQneX|Fvu$O2Hq~eJrN?#Yt*&xXz2u@G9h8g%{#-T!Aa`BD@$c!AtQn zyd1BpSK}}6nh4P_BOcy>H{wlrGv30G z`(7eFpH*EP`Ov-|D;y+>UVBzJNX-8%9M23P@kGlwNi-yZ-k`r% zkVK-RH|afwT4$q8-0ra_n@KVQjwBHa;pr`Uo8GB}JH$p(=*RRAdY7$CHzkWFjJ=}{ z6E{*4Pi za3s1z1i-Y}QSvey8Q9=JhLPc91Q}USS~R?9U}OXkKq3Gq01+UXrOQCEaZqh6A!FDy zNlHnX08#;D6=W zP?VFm1yG8aX{kfVY-ScxQ)X42r|*#un5Pk0Ir&h4xMwUTAG5ikW@X*nKo*dS2*96_ zg``{njQ|M(ul1C*=vhHFqKS3pZXsJE2YxAl zshoTzfVt+t1dWpHB)iDh1?;@insG^hByn7W7Of+LH`zn>_ERaJ57xBy)} zKobF)3TztuF@0Vu1*)#(l$?rV)vTEStp(`tyoYcaPRFvEOW?E|!?C#lEd*#;$>})* z$C5fzfL820ab?4KEp43hf2~aATpV+%jR0*0Xh+?)7Po7<2O5ZYJ4XCrE`XF=kV~tY z(n!yR+t*;sHQ+)oJqLwBU0BIP>1bjt@P*I9%QfPfvw@Xam%%mR61f*RWzOal>YuqFltm$c7mzv*bs2I5E>@C?0*-Y6|*&5j)+4r&^qn1UjjXDwaYjkw5o%e`{HJSeX(4~6BO~)grRc4ANikS4M)9g*s$#BUsbaZerDB!h3&mPRm12WplVXcvtKtX6VZ~9!F~xDk z3B@VJ8O1rpc}4i5;<7SI*-%-a9Hg9~tWa)No>X2_K2gb47FB&!NYzl)Se2>DQFT-G zRh6p7sAj3kRcloHRVP&sR1Z~;RF73p)u1NobaiueTXlPNmb#NVN8L+Zq#mXop&q4v zMLk0;s@JJEsgJ2Is4uC1Q(sm86BiXHkBf~{##zI0fw-n|ZR6UxM>7wbT>8|Oa>8Tm7c|$W-vqZC5Q>{6u`9*V1b6#^%b6NAd=9cD;=C0;` zLUcmdnvjvuDxqyc`-H57kqI*rRwwLCIFoQsTTiRe*4Ku#4YiH6O|&m)n`>KYTWQ;9 zU()u|7HS7-i?l1nng4Yud0@(9Y7%*3Q+wr!Ci3Y8PvlYS(KwYBy`Y)E?5F z(4Nws(Vo-(uDzcKi6l{yC`%ldNE4?ez8y|1Py8|QOyb?d`-u+{A0|FZe4O}H2RfpY z=wv#RE=kAhthyAPLzk*^>%2O@E~u-o>#Qr)&DE{f9oIe4TlJax{`%MS)AZBzZ|mRD zf1v+NU#_pzFV-*BFW0ZsZ`NUFd}G{+>G-Zy<{T4<^;Eix@JEi`w7JB*(ENk>agsOb#iTcrwj^Ci zx}Wq{(%(sslb%|@l3+=)*erI7)8eu;v^2A{uw+_VTf!YJ*_K>O7fUxwf6E99wM@5s zV3}|E%u;Ttw5+gvZdq+vV_9d}YT0i&V5znow0vhdX*pv#XSraxWckf<+j8IX!1B=Y zh_A;hc{Lx;C-5ddiRXDMpThh3MtmE-6Q9F(=DYGe`CfbPPuHC*i-D8_Kx-(duMxB zdoTMydy##Jz1Tj?KEgiH9<~eiDfYMQGwd_%v+Qf_-`P*v&)YBBFWaw#?YHcA?04<= z?GGF}N2a6H@v39G<5R~1$5O|7$3Dja$1%rA$7#n|$3@3w#}&sl$3v&oDR;&?l}?RQ z>(n_7PM5QxGsD@`+1%OE*~;13+0~in%y%wzu6J&5Zgg&T?se{WRyz+lzjyxVJmb9N z{LOjQdBb_v`KR-tGyIS9NvbckPwLdvS*deU-%I@!P<-7X0UU9wQddIcOwcd5qbj`@%d*1fU^?c}A-o-e+;h^a z_gcLnZ&Pm@Z&z=3?~C4E-j}@nyz{+FykB_Nd3Sh^dVltw@SgUb^Iq^?_Fnbg@ZR$N z;gk8IeBl_M!l&}Z`?Nm2&*ZcCtiBXqz}L>#&o|!pwy(ms$+ydQ%y-j|{Biy~e=q-N z|2Y3-|GWNq{!jc1{N?^d{#E`p{wn`Q{}%sN|55*~Ky;v4pmiWC&?(S8&^ypKP#72# z7#t`KObomhpn)lY8G&~Kvjbw_{lNCXjc`yGOb*(D!C<3clVG!8%V7Ip$6!vdOR!t8 zcW^*(SgGju!jN9bO< sKD~MR(Db?KpQJBJUzNTleMkEK^aHhX7{;~VT({cqnokM)O#k-(0LOqk%K!iX diff --git a/NfcLock.Ios.Binding/NfcLockFramework/NfcLockFramework/NfcLockFramework.swift b/NfcLock.Ios.Binding/NfcLockFramework/NfcLockFramework/NfcLockFramework.swift index a22fd31..7f8e9f0 100644 --- a/NfcLock.Ios.Binding/NfcLockFramework/NfcLockFramework/NfcLockFramework.swift +++ b/NfcLock.Ios.Binding/NfcLockFramework/NfcLockFramework/NfcLockFramework.swift @@ -3,32 +3,88 @@ import NFCSDK @objc(NFCManager) public class NFCManager: NSObject, NFCTagReaderSessionDelegate { + // 单例实例(改为实例属性,而非直接用 static 方法) static let instance = NFCManager() - private let helper = IOSNFCHelper() - private var session: NFCTagReaderSession? - private var readyToStart = true - private var controlName = "" + // NFCSDK 助手(改为实例属性) + let helper = IOSNFCHelper() + // NFC 会话(改为实例属性) + var session: NFCTagReaderSession? + // 控制状态(改为实例属性) + var readyToStart = true + var controlName = "" private override init() { - + super.init() + } + + // MARK: - 对外暴露的 OC 调用方法(通过单例调用实例方法) + @objc + public static func startScan() { + instance._startScan() } @objc - public func startScan() { - if (readyToStart) { + public static func endScan() { + instance._endScan() + } + + @objc + public static func endScan(errorMessage: String) { + instance._endScan(errorMessage: errorMessage) + } + + @objc + public static func setLoopCb(cb: @escaping (String, Bool, Int) -> Bool) { + instance._setLoopCb(cb: cb) + } + + @objc + public static func setFinishedCb(cb: @escaping () -> Void) { + instance._setFinishedCb(cb: cb) + } + + @objc + public static func setChargingCb(cb: @escaping (String, Int) -> Void) { + instance._setChargingCb(cb: cb) + } + + @objc + public static func setControllingCb(cb: @escaping (String, Int) -> Void) { + instance._setControllingCb(cb: cb) + } + + @objc + public static func lock(password: String) { + instance._lock(password: password) + } + + @objc + public static func unlock(password: String) { + instance._unlock(password: password) + } + + // MARK: - 实际的实例方法(核心逻辑) + private func _startScan() { + // 1. 检查设备是否支持 NFC + guard NFCTagReaderSession.readingAvailable else { + _endScan(errorMessage: "设备不支持NFC功能") + return + } + + if readyToStart { readyToStart = false + // 2. 修复语法错误:移除末尾多余的逗号 session = NFCTagReaderSession( pollingOption: [.iso14443], - delegate: self, - queue: nil, + delegate: self, // 这里必须传实例 self,而非静态的 self + queue: nil ) session?.alertMessage = "请将 iPhone 靠近设备" session?.begin() } } - @objc - public func endScan() { + private func _endScan() { session?.invalidate() Task { try? await Task.sleep(nanoseconds: 2_000_000_000) @@ -36,8 +92,7 @@ public class NFCManager: NSObject, NFCTagReaderSessionDelegate { } } - @objc - public func endScan(errorMessage: String) { + private func _endScan(errorMessage: String) { session?.invalidate(errorMessage: errorMessage) Task { try? await Task.sleep(nanoseconds: 2_000_000_000) @@ -45,28 +100,98 @@ public class NFCManager: NSObject, NFCTagReaderSessionDelegate { } } + private func _setLoopCb(cb: @escaping (String, Bool, Int) -> Bool) { + helper.setLoopCb { id, isNew, rssi in + let isNew0 = isNew.boolValue + let rssi0 = rssi?.intValue ?? 0 + self.session?.alertMessage = "检测到设备" + return KotlinBoolean(bool: cb(id, isNew0, rssi0)) + } + } + + private func _setFinishedCb(cb: @escaping () -> Void) { + helper.setFinishedCb(cb: { + self._endScan() + cb() + }) + } + + private func _setChargingCb(cb: @escaping (String, Int) -> Void) { + helper.setChargingCb { res, level in + let level0 = level?.intValue ?? 0 + switch res { + case "OK": + self.session?.alertMessage = "充电中(\(level0)%)" + case "UNAUTHORIZED": + self._endScan(errorMessage: "验证失败") + default: + self._endScan(errorMessage: "NFC 标签丢失") + } + cb(res, level0) + } + } + + private func _setControllingCb(cb: @escaping (String, Int) -> Void) { + helper.setControllingCb { res, progress in + let progress0 = progress?.intValue ?? 0 + switch res { + case "OK": + if progress0 < 100 { + self.session?.alertMessage = "\(self.controlName)中(\(progress0)%)" + } else { + self.session?.alertMessage = "\(self.controlName)成功" + } + default: + self._endScan(errorMessage: "\(self.controlName)失败") + } + cb(res, progress0) + } + } + + private func _lock(password: String) { + controlName = "关锁" + helper.lock(password: password) + } + + private func _unlock(password: String) { + controlName = "开锁" + helper.unlock(password: password) + } + + // MARK: - NFCTagReaderSessionDelegate 协议方法(必须是实例方法) + // 1. 可选方法:会话激活时调用(非必选,但建议保留) public func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) { print("NFC Session Active") } + // 2. 必选方法:会话失效/出错时调用 public func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) { - endScan() + // 区分用户主动取消和真实错误 + if let nfcError = error as? NFCReaderError { + if nfcError.code != .readerSessionInvalidationErrorUserCanceled { + print("NFC 会话错误: \(nfcError.localizedDescription)") + } + } + _endScan() } + // 3. 必选方法:检测到 NFC 标签时调用 public func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [CoreNFC.NFCTag]) { + guard let tag = tags.first else { + _endScan(errorMessage: "未检测到有效NFC标签") + return + } - guard let tag = tags.first else { return } - - session.connect(to: tag) { error in - if error != nil { - self.endScan(errorMessage: "NFC 连接失败") + session.connect(to: tag) { [weak self] error in + guard let self = self else { return } // 避免循环引用 + + if let error = error { + self._endScan(errorMessage: "NFC 连接失败: \(error.localizedDescription)") return } switch tag { - case .miFare(let miFareTag): - self.helper.setTransceiver { data, resolve in let length = Int(data.size) var buffer = [UInt8](repeating: 0, count: length) @@ -76,8 +201,8 @@ public class NFCManager: NSObject, NFCTagReaderSessionDelegate { let command = Data(buffer) miFareTag.sendMiFareCommand(commandPacket: command) { response, error in - if error != nil { - self.endScan(errorMessage: "NFC 标签丢失") + if let error = error { + self._endScan(errorMessage: "NFC 标签丢失: \(error.localizedDescription)") let _ = resolve(KotlinByteArray(size: 0)) return } @@ -94,81 +219,13 @@ public class NFCManager: NSObject, NFCTagReaderSessionDelegate { do { try await self.helper.process() } catch { - print("process error") + print("process error: \(error.localizedDescription)") } } - default: - self.endScan(errorMessage: "不是 NFC-A 标签") + self._endScan(errorMessage: "不是 NFC-A 标签") } } } - - @objc - public func setLoopCb(cb: @escaping (String, Bool, Int) -> Bool) { - helper.setLoopCb { id, isNew, rssi in - let isNew0 = isNew.boolValue - let rssi0 = rssi?.intValue ?? 0 - self.session?.alertMessage = "检测到设备" - return KotlinBoolean(bool: cb(id, isNew0, rssi0)) - } - } - - @objc - public func setFinishedCb(cb: @escaping () -> Void) { - helper.setFinishedCb(cb: { - self.endScan() - cb() - }) - } - - @objc - public func setChargingCb(cb: @escaping (String, Int) -> Void) { - helper.setChargingCb { res, level in - let level0 = level?.intValue ?? 0 - switch (res) { - case "OK": - self.session?.alertMessage = "充电中(\(level0)%)" - break - case "UNAUTHORIZED": - self.endScan(errorMessage: "验证失败") - break - default: - self.endScan(errorMessage: "NFC 标签丢失") - } - cb(res, level0) - } - } - - @objc - public func setControllingCb(cb: @escaping (String, Int) -> Void) { - helper.setControllingCb { res, progress in - let progress0 = progress?.intValue ?? 0 - switch (res) { - case "OK": - if (progress0 < 100) { - self.session?.alertMessage = "\(self.controlName)中(\(progress0)%)" - } else { - self.session?.alertMessage = "\(self.controlName)成功" - } - break - default: - self.endScan(errorMessage: "\(self.controlName)失败") - } - cb(res, progress0) - } - } - - @objc - public func lock(password: String) { - controlName = "关锁" - helper.lock(password: password) - } - - @objc - public func unlock(password: String) { - controlName = "开锁" - helper.unlock(password: password) - } }