我正在开发一个与ISO15693芯片交互的iOS NFC应用程序。
我需要通过NFC发送多个连续的命令,这些命令将被逐个执行,我需要等待上一个命令的结果来执行下一个命令。
从今天开始,我使用:
DispatchQueue.global().async {
DispatchQueue.global().sync {
var fw_id = NFCUtils.sendI2CCommand(tag: self.tag!, command: NFCConstants.CONFIG_FW_ID)
print("Read FirmwareID \(fw_id)")
var sw_id = NFCUtils.sendI2CCommand(tag: self.tag!, command: NFCConstants.CONFIG_SW_ID)
print("Read SotfwareID \(sw_id)")
var ex_id = NFCUtils.sendI2CCommand(tag: self.tag!, command: NFCConstants.CONFIG_EX_ID)
print("Read ExternalID \(ex_id)")
}
}
命令被一个接一个地正确执行。
但在sendI2C命令中:
public static func sendI2CCommand(tag: NFCISO15693Tag, command: UInt8) -> String{
var res:String = ""
tag.sendRequest(requestFlags: 0x12, commandCode: 0xD4, data: Data([0x04, 0x02, 0x00, command]))
{ result in
switch result {
case .success(( let responseFlag as NFCISO15693ResponseFlag, let response as Data)):
break
case .failure(_):
break
default:
tag.sendRequest(requestFlags: 0x12, commandCode: 0xD5, data: Data([0x04, 0x02, 0x00]))
{ result in
switch result {
case .success(( let responseFlag as NFCISO15693ResponseFlag, let response2 as Data)):
break
case .failure(_):
break
default:
tag.sendRequest(requestFlags: 0x12, commandCode: 0xD2, data: Data([0x04, 0x00, 0x06]))
{ result in
switch result {
case .success(( let responseFlag as NFCISO15693ResponseFlag, let response2 as Data)):
var foo = response2
foo.insert(responseFlag.rawValue, at: 0)
let responseHex = foo.hexadecimalCompressed.substring(with: 2..<4)
res = responseHex
break
case .failure(_):
break
default:
break
}
}
break
}
}
break
}
}
usleep(50000)
return res
}
sendI2CCommand正在发送两个连续的NFC命令。但是即使调用在DispatchQueue同步中,函数的结果也不会等待执行结束,并且我需要在返回值之前添加一个非常难看的usleep(50000)
,否则结果为空,并且不会返回任何数据,因为APDU命令需要一些时间才能执行。
我还尝试在函数中使用信号量,但它阻止了我的APDU命令:
let semaphore = DispatchSemaphore(value: 0)
在函数开始时
semaphore.signal()
等我处理完了
然后呢
semaphore.wait()
但在处理过程中崩溃。
那么,如何避免使用usleep
函数等待处理结束后才返回函数中的结果呢?
2条答案
按热度按时间0ejtzxu11#
你不能像这样去做你所描述的事情。你会阻塞你不允许阻塞的共享线程。这正是async/await和CheckedContinuation的设计目的。
您必须确保只调用
.resume
一次。然后你的顶层代码变成:
z4iuyo4d2#
如果你不想让
sendI2CCommand
返回结果,那么你可以使用DispatchGroup
,如下所示:您也可以从调用代码中删除
DispatchGroup.global().sync
:另一种选择是修改
sendI2CCommand
以接受完成处理程序:然后调用代码看起来像这样: