Swift sending multiple HTTP POST requests synchronously












0















In my code I need to send multiple HTTP POST commands to a server, depending on user selection (user picks pictures, and each command contains one picture).



I need to send first a document via HTTP POST, then n HTTP POST for the pictures and at the end a last HTTP POST to commit. Currently it is working almost fine, but if there are too many HTTP POST commands sent in // I have some HTTP errors (for instance 16 pics of 21 are sent)



Hence, I would like to make sure that each HTTP command are sent one by one to the server after the previous one has been sent successfully.



Here is the code I'm using:



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

})


Currently I have the following behavior:




  • Send HTTP POST Document

  • When the HTTP POST document is finished the entire HTTP POST Photos are sent

  • When the entire HTTPO POST photos are sent the HTTP POST Commit is sent.


but I would like to get HTTP POST Photo sent one by one.



How Can I achieve this ?



EDIT 1



I also tried to use semaphore and Dispatcher like this:



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;

}
}


but the HTTP request in the method dummyHTTPPOST() is never sent....session.DataTask is never started.










share|improve this question

























  • How are you actually dispatching the data? Are you using URLSession.dataTask? Can you use the completion block for dataTask to send the next image in the queue if the previous upload was successful?

    – CPR
    Nov 23 '18 at 18:34











  • yes I'm using URLSession.dataTask, currently I'm using only the completion block to inform the end of the HTTP command with a callback to continue in my main for loop.

    – tiamat
    Nov 23 '18 at 19:30
















0















In my code I need to send multiple HTTP POST commands to a server, depending on user selection (user picks pictures, and each command contains one picture).



I need to send first a document via HTTP POST, then n HTTP POST for the pictures and at the end a last HTTP POST to commit. Currently it is working almost fine, but if there are too many HTTP POST commands sent in // I have some HTTP errors (for instance 16 pics of 21 are sent)



Hence, I would like to make sure that each HTTP command are sent one by one to the server after the previous one has been sent successfully.



Here is the code I'm using:



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

})


Currently I have the following behavior:




  • Send HTTP POST Document

  • When the HTTP POST document is finished the entire HTTP POST Photos are sent

  • When the entire HTTPO POST photos are sent the HTTP POST Commit is sent.


but I would like to get HTTP POST Photo sent one by one.



How Can I achieve this ?



EDIT 1



I also tried to use semaphore and Dispatcher like this:



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;

}
}


but the HTTP request in the method dummyHTTPPOST() is never sent....session.DataTask is never started.










share|improve this question

























  • How are you actually dispatching the data? Are you using URLSession.dataTask? Can you use the completion block for dataTask to send the next image in the queue if the previous upload was successful?

    – CPR
    Nov 23 '18 at 18:34











  • yes I'm using URLSession.dataTask, currently I'm using only the completion block to inform the end of the HTTP command with a callback to continue in my main for loop.

    – tiamat
    Nov 23 '18 at 19:30














0












0








0








In my code I need to send multiple HTTP POST commands to a server, depending on user selection (user picks pictures, and each command contains one picture).



I need to send first a document via HTTP POST, then n HTTP POST for the pictures and at the end a last HTTP POST to commit. Currently it is working almost fine, but if there are too many HTTP POST commands sent in // I have some HTTP errors (for instance 16 pics of 21 are sent)



Hence, I would like to make sure that each HTTP command are sent one by one to the server after the previous one has been sent successfully.



Here is the code I'm using:



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

})


Currently I have the following behavior:




  • Send HTTP POST Document

  • When the HTTP POST document is finished the entire HTTP POST Photos are sent

  • When the entire HTTPO POST photos are sent the HTTP POST Commit is sent.


but I would like to get HTTP POST Photo sent one by one.



How Can I achieve this ?



EDIT 1



I also tried to use semaphore and Dispatcher like this:



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;

}
}


but the HTTP request in the method dummyHTTPPOST() is never sent....session.DataTask is never started.










share|improve this question
















In my code I need to send multiple HTTP POST commands to a server, depending on user selection (user picks pictures, and each command contains one picture).



I need to send first a document via HTTP POST, then n HTTP POST for the pictures and at the end a last HTTP POST to commit. Currently it is working almost fine, but if there are too many HTTP POST commands sent in // I have some HTTP errors (for instance 16 pics of 21 are sent)



Hence, I would like to make sure that each HTTP command are sent one by one to the server after the previous one has been sent successfully.



Here is the code I'm using:



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

})


Currently I have the following behavior:




  • Send HTTP POST Document

  • When the HTTP POST document is finished the entire HTTP POST Photos are sent

  • When the entire HTTPO POST photos are sent the HTTP POST Commit is sent.


but I would like to get HTTP POST Photo sent one by one.



How Can I achieve this ?



EDIT 1



I also tried to use semaphore and Dispatcher like this:



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;

}
}


but the HTTP request in the method dummyHTTPPOST() is never sent....session.DataTask is never started.







swift grand-central-dispatch






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 20:07







tiamat

















asked Nov 23 '18 at 15:09









tiamattiamat

350316




350316













  • How are you actually dispatching the data? Are you using URLSession.dataTask? Can you use the completion block for dataTask to send the next image in the queue if the previous upload was successful?

    – CPR
    Nov 23 '18 at 18:34











  • yes I'm using URLSession.dataTask, currently I'm using only the completion block to inform the end of the HTTP command with a callback to continue in my main for loop.

    – tiamat
    Nov 23 '18 at 19:30



















  • How are you actually dispatching the data? Are you using URLSession.dataTask? Can you use the completion block for dataTask to send the next image in the queue if the previous upload was successful?

    – CPR
    Nov 23 '18 at 18:34











  • yes I'm using URLSession.dataTask, currently I'm using only the completion block to inform the end of the HTTP command with a callback to continue in my main for loop.

    – tiamat
    Nov 23 '18 at 19:30

















How are you actually dispatching the data? Are you using URLSession.dataTask? Can you use the completion block for dataTask to send the next image in the queue if the previous upload was successful?

– CPR
Nov 23 '18 at 18:34





How are you actually dispatching the data? Are you using URLSession.dataTask? Can you use the completion block for dataTask to send the next image in the queue if the previous upload was successful?

– CPR
Nov 23 '18 at 18:34













yes I'm using URLSession.dataTask, currently I'm using only the completion block to inform the end of the HTTP command with a callback to continue in my main for loop.

– tiamat
Nov 23 '18 at 19:30





yes I'm using URLSession.dataTask, currently I'm using only the completion block to inform the end of the HTTP command with a callback to continue in my main for loop.

– tiamat
Nov 23 '18 at 19:30












1 Answer
1






active

oldest

votes


















0














I finally found a solution to send synchronously multiple HTTP POST commands using session.DataTask.



Here is the solution:



        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("************************")
}
}


Hope it will help other people.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449058%2fswift-sending-multiple-http-post-requests-synchronously%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I finally found a solution to send synchronously multiple HTTP POST commands using session.DataTask.



    Here is the solution:



            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("************************")
    }
    }


    Hope it will help other people.






    share|improve this answer




























      0














      I finally found a solution to send synchronously multiple HTTP POST commands using session.DataTask.



      Here is the solution:



              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("************************")
      }
      }


      Hope it will help other people.






      share|improve this answer


























        0












        0








        0







        I finally found a solution to send synchronously multiple HTTP POST commands using session.DataTask.



        Here is the solution:



                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("************************")
        }
        }


        Hope it will help other people.






        share|improve this answer













        I finally found a solution to send synchronously multiple HTTP POST commands using session.DataTask.



        Here is the solution:



                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("************************")
        }
        }


        Hope it will help other people.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 24 '18 at 9:50









        tiamattiamat

        350316




        350316






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449058%2fswift-sending-multiple-http-post-requests-synchronously%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Feedback on college project

            Futebolista

            Albești (Vaslui)