Swift синхронно отправляет несколько HTTP-запросов POST

В моем коде мне нужно отправить несколько команд 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
  • Когда документ HTTP POST завершен, отправляются все фотографии HTTP POST.
  • Когда отправляются все фотографии HTTPO POST, отправляется фиксация HTTP POST.

но я хотел бы получать фотографии 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? Можете ли вы использовать блок завершения для dataTask, чтобы отправить следующее изображение в очереди, если предыдущая загрузка была успешной?

CPR 23.11.2018 19:34

да, я использую URLSession.dataTask, в настоящее время я использую только блок завершения, чтобы сообщить об окончании HTTP-команды с помощью обратного вызова для продолжения в моем основном цикле for.

tiamat 23.11.2018 20:30
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
332
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец-то я нашел решение для синхронной отправки нескольких команд 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("************************")
        }
    }

Надеюсь, это поможет другим людям.

Другие вопросы по теме