iOS应用处于前台时如何禁用Apple Wallet自动唤起
iOS前台运行时屏蔽NFC标签唤起Apple Wallet的实现方案
首先明确问题触发逻辑:iOS系统会对两类NFC标签默认触发前台唤起Apple Wallet的行为,一类是NDEF payload包含关联Wallet服务Universal Link的普通标签,另一类是Apple专属加密标签(绑定Wallet的银行卡/交通卡/凭证、HomeKit钥匙标签等),两类场景的拦截方案不同:
- 方案1:优先占用NFC控制器,拦截普通标签触发逻辑
当你的应用在前台持有激活状态的Core NFC读取会话时,系统会将NFC标签的读取事件优先派发给你的应用,不会触发Wallet唤起,这是官方允许的最通用方案:- 提前在项目
Info.plist中添加NFCReaderUsageDescription权限说明,描述你使用NFC的业务场景 - 在应用进入前台时立刻启动
NFCTagReaderSession,不要等到用户手动触发扫描 - 会话读取到标签处理完业务逻辑后,调用
restartPolling()保持会话持续运行,不要直接销毁会话;如果会话意外失效,在错误回调里延迟重启会话,避免出现权限空窗
核心实现代码:
- 提前在项目
import CoreNFC class NFCService: NSObject, NFCTagReaderSessionDelegate { private var scanSession: NFCTagReaderSession? func startForegroundScan() { scanSession = NFCTagReaderSession( pollingOption: [.iso14443, .iso15693, .iso18092], delegate: self, queue: .main ) scanSession?.alertMessage = "将标签靠近手机顶部完成读取" scanSession?.begin() } func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) { // 在这里实现你自己的标签读取、业务处理逻辑 // 处理完成后重启轮询,保持会话激活 session.restartPolling() } func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) { // 会话非主动失效时,延迟重启避免空窗 if (error as NSError).code != NFCReaderError.Code.readerSessionInvalidationErrorUserCanceled.rawValue { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.startForegroundScan() } } } func stopScan() { scanSession?.invalidate() scanSession = nil } }
注意:在应用退到后台时要主动调用stopScan()销毁会话,避免不必要的权限占用和电量消耗。
方案2:配置关联域名拦截Wallet专属Universal Link
如果你业务中用到的NFC标签NDEF区域写入的是固定的、关联Wallet服务的URL,可以在Xcode中开启Associated Domains能力,添加对应域名的applinks:配置,同时实现应用的Universal Link处理回调。系统识别到你的应用可以处理该标签内的链接时,会优先把事件交给你的应用,不会跳转Wallet。该方案仅对写入公开URL的普通NDEF标签有效。不可绕过的系统限制
对于Apple加密的专属NFC标签(包括EMV标准银行卡、Apple官方发行的Wallet凭证/交通卡、HomeKit配对标签等),系统设置了最高优先级的安全触发逻辑,所有第三方App的NFC会话权限都低于系统内置服务,目前没有任何公开API可以拦截这类标签唤起Wallet。任何尝试使用私有API绕过该限制的行为都会被App Store审核拒绝。
内容的提问来源于stack exchange,提问作者Nver Abgaryan
相关产品推荐
相关产品推荐

