将完成处理程序添加到框架的委托函数以进行响应处理(爱普生打印机)

Adding a completion handler to a framework's delegate function for response handling (Epson Printer)

所以我有处理打印作业队列的逻辑(这就是我们所有其他打印机集成的处理方式),它为每台打印机调用特定函数(在本例中,sendCommand 函数)执行打印作业,然后报告成功/失败,以便我们可以正确处理重试或删除打印作业文档。

func sendCommand(_ commands: Data, portName: String, portSettings: String, timeoutMilis: uint_least32_t) -> Bool {
    doPrinterSetup()
    let succPrint = cutAndCompletePrintJob(commands)
    if (connectedPrinter != nil) {
        disconnectPrinter()
    }
    while (!hasCompleted) { //Awful solution?
        sleep(1)
    }
    return printSuccess
}

在打印机的特定逻辑中,我建立连接、构建打印数据等...然后发送。我得到的响应是命令已发送成功。

func printData(_ data: Data) -> Bool {
    if connectedPrinter == nil {
        return false
    }
    connectedPrinter!.addCommand(data) //Add print information
    connectedPrinter!.addCut(EPOS2_CUT_FEED.rawValue) //Add cut
    connectedPrinter!.beginTransaction()
    connectedPrinter!.sendData(Int(EPOS2_PARAM_DEFAULT))
    return true
}

EPOS 框架有一个单独的委托函数,onPtrReceive 在打印作业实际完成打印后调用,如下所示,它实际报告打印成功或失败工作:

//EPOS Delegate func
func onPtrReceive(_ printerObj: Epos2Printer!, code: Int32, status: Epos2PrinterStatusInfo!, printJobId: String!) { 
    hasCompleted = true
    
    print("Status in onPtrReceive \(makeErrorMessage(status))")
    
    dispPrinterWarnings(status)
    
    DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async(execute: {
        self.connectedPrinter!.endTransaction()
        self.connectedPrinter!.disconnect()
        self.connectedPrinter!.clearCommandBuffer()
        self.connectedPrinter!.setReceiveEventDelegate(nil)
        })
}

现在,问题是在响应我的 parent class 处理打印作业之前,我必须等待对 sendCommand 的响应,但是我不知道如何将完成处理程序实际传递给框架委托函数并以正确的方式进行。目前我有全局变量 hasCompleted 我有一个 while 循环阻止它响应直到 onPtrReceive 将它设置为 true,但是我印象深刻这是一个糟糕的解决方案。关于如何以正确的方式处理这个问题或者这是一个可以接受的策略有什么建议吗?

你可以使用闭包来解决这个问题。

sendCommand方法添加一个闭包参数并移除Bool return值,保持这个参数为你class 属性.

// Bool stand for the status of this printing job, true means success.
var completion: ((Bool) -> Void)?

func sendCommand(_ commands: Data, portName: String, portSettings: String, timeoutMilis: uint_least32_t, completion: @escaping (Bool -> Void)?) {
    self.completion = completion
    // ....
}

在委托方法中调用这个闭包。

func onPtrReceive(_ printerObj: Epos2Printer!, code: Int32, status: Epos2PrinterStatusInfo!, printJobId: String!) {
      
    let success = isPrintJobSuccess(by: code) // determine how a job is succeed
    self.completion?(success)
}

假设您的 class 名为 Printer,您可以在您的网站上执行此操作:

let printer = Printer()
printer.sendData(cmdData, portName: "port", portSettings: "settings", timeoutMilis: 1000, completion: { success in 
    if success {
        doSomeSuccessJob()
    }
})
// or you could use trailing closure
printer.sendData(cmdData, portName: "port", portSettings: "settings", timeoutMilis: 1000) { success in 
    if success {
        doSomeSuccessJob()
    }
}

参考文献:https://docs.swift.org/swift-book/LanguageGuide/Closures.html