在执行下一个操作之前等待请求完成

时间:2016-10-06 14:46:54

标签: ios swift swift2

我想知道在执行另一段代码之前如何等待发送请求完成上传(并获得响应)的操作。我试图用NSOperations做到这一点:

    let testOp = BlockOperation {
        var result = 0

        for i in 1...1000000000 {
            result += i
        }
    }

    let logOp = BlockOperation {
        self.debug.log(tag: "test", content: "testing")
    }

    logOp.completionBlock = {
        print("------- logOp completed")
    }

    logOp.addDependency(testOp)

    let sendOp = BlockOperation {
        self.debug.sendLog() //uploads log, using URLSession.shared.dataTask
    }

    sendOp.completionBlock = {
        print("------- sendOp completed")
    }

    sendOp.addDependency(logOp)

    let emptyOp = BlockOperation {
        self.debug.empty()
    }

    emptyOp.completionBlock = {
        print("------- emptyOp completed")
    }

    emptyOp.addDependency(sendOp)

    let queue = OperationQueue()
    queue.addOperations([testOp, logOp, sendOp, emptyOp], waitUntilFinished: false)

输出:

------- logOp completed
*** Sending debug log (coming from self.debug.sendLog())
------- sendOp completed
------- emptyOp completed
*** sendLog uploaded (coming from self.debug.sendLog())

根据我的代码,我希望输出为:

------- logOp completed
*** Sending debug log
*** sendLog uploaded
------- sendOp completed
------- emptyOp completed

我该怎么做?我可以用NSOperations做到这一点吗?

有关debug.sendLog()函数的更多详细信息:

func sendLog() {
    ...
    var urlRequest = URLRequest(url: url!)
    urlRequest.httpMethod = "POST"
    ...

    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest, completionHandler: {
        (data, response, error) in

        ...

        DispatchQueue.main.async {
            print("*** sendLog uploaded")

        }
    })

    task.resume()
}

1 个答案:

答案 0 :(得分:3)

您可以直接将完成块添加到sendLog方法并丢弃所有块操作内容。

func sendLog(withCompletion completion: (() -> Void)) {
    ...
    var urlRequest = URLRequest(url: url!)
    urlRequest.httpMethod = "POST"
    ...

    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest, completionHandler: {
        (data, response, error) in

        ...
        completion?()
    })

    task.resume()
}

然后按照以下方式调用sendLog方法:

sendLog(withCompletion: {
   // Execute the code you want to happen on completion here.
})