В моем коде мне нужно отправить несколько команд HTTP POST на сервер, в зависимости от выбора пользователя (пользователь выбирает изображения, и каждая команда содержит одно изображение).
Мне нужно сначала отправить документ через HTTP POST, затем n HTTP POST для изображений и в конце последний HTTP POST для фиксации. В настоящее время он работает почти нормально, но если отправлено слишком много команд HTTP POST, // у меня есть некоторые HTTP-ошибки (например, отправлено 16 изображений из 21)
Следовательно, я хотел бы убедиться, что каждая HTTP-команда отправляется на сервер одну за другой после успешной отправки предыдущей.
Вот код, который я использую:
self.sendDocument{ (response) in
if let result = response as? Bool {
if (result == true){
self.Documentsent = true
print("Document sent, now sending photos")
progressDownload.progress = 0.3
var i = 0;
var j = 0;
//now we are sending the Photos !
for it in selectedPictures.sharedInstance.selectedCells{
let fileName = PhotoGallery.sharedInstance.photoGallery[it.item].fileName
self.constatImage = self.getSavedImage(named: fileName!)!
self.semaphore.signal()
self.envoiPhoto(obj: PhotoGallery.sharedInstance.photoGallery[it.item], pic: self.constatImage, num: it.item){ (result) -> () in
print("Envoi Photo \(it.item): \(result)")
print("i: \(i), count: \(selectedPictures.sharedInstance.selectedCells.count)")
_ = self.semaphore.wait(timeout: DispatchTime.distantFuture)
if (i == selectedPictures.sharedInstance.selectedCells.count-1){
print("for loop all pictures are sent")
self.allPhotosSent = true
self.myGroup.leave()
}
i = i+1
}
if (progressDownload.progress != 0.8){
progressDownload.progress += 0.2
}
j = j+1;
}
}
//Case when document sending is failed
else{
self.Constatsent = false
}
}
}
self.myGroup.notify(queue: .main, execute: {
print("in notify: we have sent all the pictures")
if (self.Documentsent && self.allPhotosSent){
alertController.dismiss(animated: true, completion: ({
if (Constat.sharedInstance.type == "4"){
sleep(2)
self.envoiCommit()
}
self.envoiSuccess()
}))
}
else{
print("error")
alertController.dismiss(animated: true, completion: ({
self.envoiError()
}))
}
})
В настоящее время у меня такое поведение:
но я хотел бы получать фотографии HTTP POST, отправленные по одному.
Как я могу этого добиться?
РЕДАКТИРОВАТЬ 1
Я также пробовал использовать семафор и Диспетчер вот так:
var i: Int = 0
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "test")
let dispatchSemaphore = DispatchSemaphore(value: 0)
DispatchQueue.main.async{
while(i<50){
dispatchGroup.enter()
print("This is a synchronized closure iteration: \(i)")
self.dummyHTTPPOST{ (response) in
if let result = response as? Bool {
if (result == true){
print("HTTP POST Sent")
dispatchSemaphore.signal()
dispatchGroup.leave()
}}
}
print("round finished")
dispatchSemaphore.wait()
i = i+1;
}
}
но HTTP-запрос в методе dummyHTTPPOST () никогда не отправляется .... session.DataTask никогда не запускается.
да, я использую URLSession.dataTask, в настоящее время я использую только блок завершения, чтобы сообщить об окончании HTTP-команды с помощью обратного вызова для продолжения в моем основном цикле for.





Наконец-то я нашел решение для синхронной отправки нескольких команд HTTP POST с помощью session.DataTask.
Вот решение:
var i: Int = 0
let dispatchSemaphore = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async{
while(i<500){
self.dispatchGroup.enter()
print("-------------------------------------------------------------------------")
print("This is a synchronized iteration: \(i)")
self.dummyHTTPPOST{ (response) in
if let result = response as? Bool {
if (result == true){
print("HTTP POST Sent")
dispatchSemaphore.signal()
}}
}
print("round finished")
dispatchSemaphore.wait()
if (i == 49){
print("sent all HTTP Commands")
self.dispatchGroup.leave()
}
i = i+1;
}
DispatchQueue.main.async {
print("************************")
print("everything has been sent in Dispatch Queue")
print("************************")
}
}
Надеюсь, это поможет другим людям.
Как вы на самом деле отправляете данные? Вы используете
URLSession.dataTask? Можете ли вы использовать блок завершения дляdataTask, чтобы отправить следующее изображение в очереди, если предыдущая загрузка была успешной?