在 Swift 中的所有事件完成后,DispatchGroup 通知方法应该只 运行 一次
DispatchGroup notify method should only run once after all events are finished in Swift
我有下面使用“DispatchGroup”的代码:
// class variables
let myUploadGroup = DispatchGroup()
var concatenatedUploadGroupMessage:String = ""
// inside a method I have the code below
for resFoto in resFotosResenhaEscolhidas {
myUploadGroup.enter()
jsonRequestUploadImagem = ResFotosModel.createJsonFotoResenha(resFoto, resenhaDados.IdGedave)
let requestUploadImagem: NSMutableURLRequest = serviceRepository.clientURLRequest(wsUploadImagem, typeAutho: .basic, parms: "", body: jsonRequestUploadImagem as Dictionary<String, AnyObject>)
serviceRepository.post(requestUploadImagem, retryLogin: true, completion: {isOk,msgError,httpCode,needLogin,response in
self.checkResponseUploadImagemFotoResenha(response as AnyObject, httpCode)
})
}
func checkResponseUploadImagemFotoResenha(_ response:AnyObject, _ httpCode:Int) {
if httpCode != 200 {
let string = String(data: response as! Data, encoding: .utf8)
print( string!+" \n Erro HTTP: "+String(httpCode) )
myUploadGroup.leave()
AlertActions.showBasicAlert(erroParaExibir: string!+" \n Erro HTTP: "+String(httpCode), currentView: self)
} else {
// httpCode == 200
let data: Data = response as! Data // received from a network request, for example
let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: [])
guard let dictionary = jsonResponse as? [String: Any] else { return }
guard let nestedDictionary = dictionary["RetornoGravacaoImagemWSVO"] as? [String: Any] else { return }
let mensagem = nestedDictionary["mensagem"] as! String
let codigo = nestedDictionary["codigo"] as! Int
if codigo != 200 {
print("Erro upload foto - codigo: \(codigo)")
concatenatedUploadGroupMessage = concatenatedUploadGroupMessage+" \(mensagem) - \(codigo) \n"
} else {
let nomeArquivo = nestedDictionary["nomeArquivo"] as! String
concatenatedUploadGroupMessage = concatenatedUploadGroupMessage+" \(nomeArquivo) - \(mensagem) \n"
}
myUploadGroup.leave()
}
myUploadGroup.notify(queue: DispatchQueue.main) {
AlertActions.showBasicAlert(erroParaExibir: self.concatenatedUploadGroupMessage, currentView: self)
print("Finished all requests.")
CustomLoadingBar.hide(self) // use in conjunction with the Grand Dispatcher Group
}
}
我使用“myUploadGroup.enter()”和“myUploadGroup.leave()”发送信号来开始和结束请求。
之后我有了方法“myUploadGroup.notify”。
当所有请求都发出后,例如,开始了 4 个 http 请求,当它们完成时,我可以看到消息“完成所有请求”。在控制台打印4次。
我想做的是当 4 个 http 请求完成后,我只想看到消息消息“完成所有请求”。在控制台上打印一次,而不是看到消息打印 4 次。
我该怎么做?
您正在函数 checkResponseUploadImagemFotoResenha()
中调用 myUploadGroup.notify()
,这是从完成处理程序调用的。这意味着您不止一次调用 myUploadGroup.notify()
。不要那样做。
像这样重写将请求排队的代码:
for requestInfo in requests {
myUploadGroup.enter()
submitRequest( completion: {
// Process response
myUploadGroup.leave()
}
myUploadGroup.notify(queue: DispatchQueue.main) {
// Code to execute once when all the requests have completed
}
请注意我是如何在提交请求的循环之后调用通知的。
我能够找到解决我的问题的方法,而无需重写我的代码来排队我的请求。
我创建了一个 class 变量
var counter:Int = 0
在我的“myUploadGroup.enter()”函数之前添加以下代码
counter = counter + 1
在我的“myUploadGroup.notify”函数中,我添加了这段代码
self.counter = self.counter - 1
if self.counter == 0 {
print("I run once")
}
现在对我有用了。
我有下面使用“DispatchGroup”的代码:
// class variables
let myUploadGroup = DispatchGroup()
var concatenatedUploadGroupMessage:String = ""
// inside a method I have the code below
for resFoto in resFotosResenhaEscolhidas {
myUploadGroup.enter()
jsonRequestUploadImagem = ResFotosModel.createJsonFotoResenha(resFoto, resenhaDados.IdGedave)
let requestUploadImagem: NSMutableURLRequest = serviceRepository.clientURLRequest(wsUploadImagem, typeAutho: .basic, parms: "", body: jsonRequestUploadImagem as Dictionary<String, AnyObject>)
serviceRepository.post(requestUploadImagem, retryLogin: true, completion: {isOk,msgError,httpCode,needLogin,response in
self.checkResponseUploadImagemFotoResenha(response as AnyObject, httpCode)
})
}
func checkResponseUploadImagemFotoResenha(_ response:AnyObject, _ httpCode:Int) {
if httpCode != 200 {
let string = String(data: response as! Data, encoding: .utf8)
print( string!+" \n Erro HTTP: "+String(httpCode) )
myUploadGroup.leave()
AlertActions.showBasicAlert(erroParaExibir: string!+" \n Erro HTTP: "+String(httpCode), currentView: self)
} else {
// httpCode == 200
let data: Data = response as! Data // received from a network request, for example
let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: [])
guard let dictionary = jsonResponse as? [String: Any] else { return }
guard let nestedDictionary = dictionary["RetornoGravacaoImagemWSVO"] as? [String: Any] else { return }
let mensagem = nestedDictionary["mensagem"] as! String
let codigo = nestedDictionary["codigo"] as! Int
if codigo != 200 {
print("Erro upload foto - codigo: \(codigo)")
concatenatedUploadGroupMessage = concatenatedUploadGroupMessage+" \(mensagem) - \(codigo) \n"
} else {
let nomeArquivo = nestedDictionary["nomeArquivo"] as! String
concatenatedUploadGroupMessage = concatenatedUploadGroupMessage+" \(nomeArquivo) - \(mensagem) \n"
}
myUploadGroup.leave()
}
myUploadGroup.notify(queue: DispatchQueue.main) {
AlertActions.showBasicAlert(erroParaExibir: self.concatenatedUploadGroupMessage, currentView: self)
print("Finished all requests.")
CustomLoadingBar.hide(self) // use in conjunction with the Grand Dispatcher Group
}
}
我使用“myUploadGroup.enter()”和“myUploadGroup.leave()”发送信号来开始和结束请求。
之后我有了方法“myUploadGroup.notify”。
当所有请求都发出后,例如,开始了 4 个 http 请求,当它们完成时,我可以看到消息“完成所有请求”。在控制台打印4次。
我想做的是当 4 个 http 请求完成后,我只想看到消息消息“完成所有请求”。在控制台上打印一次,而不是看到消息打印 4 次。
我该怎么做?
您正在函数 checkResponseUploadImagemFotoResenha()
中调用 myUploadGroup.notify()
,这是从完成处理程序调用的。这意味着您不止一次调用 myUploadGroup.notify()
。不要那样做。
像这样重写将请求排队的代码:
for requestInfo in requests {
myUploadGroup.enter()
submitRequest( completion: {
// Process response
myUploadGroup.leave()
}
myUploadGroup.notify(queue: DispatchQueue.main) {
// Code to execute once when all the requests have completed
}
请注意我是如何在提交请求的循环之后调用通知的。
我能够找到解决我的问题的方法,而无需重写我的代码来排队我的请求。
我创建了一个 class 变量
var counter:Int = 0
在我的“myUploadGroup.enter()”函数之前添加以下代码
counter = counter + 1
在我的“myUploadGroup.notify”函数中,我添加了这段代码
self.counter = self.counter - 1
if self.counter == 0 {
print("I run once")
}
现在对我有用了。