0

所以我有逻辑处理打印作业队列(这是我们所有其他打印机集成的处理方式),它为执行打印作业的每台打印机(在本例中为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)
        })
}

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

4

1 回答 1

0

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

向方法添加闭包参数sendCommand并删除 Bool 返回值,将此参数作为类属性保存。

// 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)
}

假设您的课程被称为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

于 2021-05-14T02:50:18.873 回答