6 Replies
      Latest reply on May 20, 2019 4:32 AM by karisli
      karisli Level 1 Level 1 (0 points)

        hi,I have some question when i use background session to upload

        if i upload a big file with backgroundConfiguration and make the app into background  ,the example1 delegate method will be called back like this

        example1

        applicationDidEnterBackground
        
        bytesSent: 32768, totoalBytesSent 11960320 ,totalBytesExpectedToSend: 52428800
        bytesSent: 32768, totoalBytesSent 11993088 ,totalBytesExpectedToSend: 52428800
        
        application:handleEventsForBackgroundURLSession:completionHandler:
        
        request = 3335 URLSession:task:didCompleteWithError:
        
        URLSessionDidFinishEventsForBackgroundURLSession:

        everything is ok

        example2:

        but when i  use multitasking upload,i will add them to an operationArray and i will take five tasks from the queue,when a task have completed and i will take a new  task from  operationArray to resume ,the delegate method will be called back linke this

        applicationDidEnterBackground
        
        bytesSent: 32768, totoalBytesSent 3211264 ,totalBytesExpectedToSend: 5242880
        ...
        bytesSent: 32768, totoalBytesSent 4947968 ,totalBytesExpectedToSend: 5242880
        
        
        application:handleEventsForBackgroundURLSession:completionHandler:
        
        request = 3363 URLSession:task:didCompleteWithError:
        request = 3361 URLSession:task:didCompleteWithError:
        request = 3365 URLSession:task:didCompleteWithError:
        
        [task][3367]take  task[3367] from array
        
        request = 3362 URLSession:task:didCompleteWithError:
        request = 3366 URLSession:task:didCompleteWithError:
        
        URLSessionDidFinishEventsForBackgroundURLSession:
        
        [task][3368]take task [3368] from array
        [task][3369]take task[3369] from array
        [task][3364]take task[3364] from array
        [task][3370]take task[3370] from array
        
        bytesSent: 32768, totoalBytesSent 32768 ,totalBytesExpectedToSend: 5242880
        ...
        bytesSent: 32768, totoalBytesSent 1638400 ,totalBytesExpectedToSend: 5242880
        
        application:handleEventsForBackgroundURLSession:completionHandler:
        
        request = 3367 URLSession:task:didCompleteWithError:
        request = 3368 URLSession:task:didCompleteWithError:
        
        
        URLSessionDidFinishEventsForBackgroundURLSession:
        
        bytesSent: 32768, totoalBytesSent 32768 ,totalBytesExpectedToSend: 5242880
        ...
        bytesSent: 32768, totoalBytesSent 1802240 ,totalBytesExpectedToSend: 5242880
        
        application:handleEventsForBackgroundURLSession:completionHandler:
        
        request = 3370 URLSession:task:didCompleteWithError:
        request = 3369 URLSession:task:didCompleteWithError:
        request = 3364 URLSession:task:didCompleteWithError:
        
        URLSessionDidFinishEventsForBackgroundURLSession:

        the example2  is different from   example1 is that  example2 have progress calll back ,should it have progress call back when a task was completed in background?

         

         

        there are alse have some strange logs , the URLSession:task:didCompleteWithError  will called back after  URLSessionDidFinishEventsForBackgroundURLSession: like this:

         

        [task][3339]take task from array 
        
        applicationDidEnterBackground 
        
        bytesSent: 32768, totoalBytesSent 32768 ,totalBytesExpectedToSend: 5242880
        ...
        bytesSent: 32768, totoalBytesSent 1998848 ,totalBytesExpectedToSend: 5242880
        
        application:handleEventsForBackgroundURLSession:completionHandler:
        
        URLSessionDidFinishEventsForBackgroundURLSession:
        
        request = 3339 URLSession:task:didCompleteWithError:
        • Re: background multitasking upload
          eskimo Apple Staff Apple Staff (12,475 points)

          should it have progress call back when a task was completed in background?

          In general, a background session won’t resume (or relaunch) your app in the background solely to give it progress callbacks.  However, if you’re missing the progress events after being brought to the front, it’s possible that you’re being affected bug the bug discussed on this thread.

          but when i use multitasking upload, i will add them to an operationArray and i will take five tasks from the queue, when a task have completed and i will take a new  task from operationArrayto resume

          How many tasks are you dealing with here?  The approach you’ve described in not one we recommend because of the resume rate limiter.  See the following posts for more:

          In general, it’s better to present all of your uploads to the session and let it deal with them.  However, that’s only viable if there’s a reasonable number of uploads.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: background multitasking upload
              karisli Level 1 Level 1 (0 points)

              thank you for the reply.

               

              i  thought about  rate limiter ,The reason why I did this because when I enter the background  after a long time and then enter the foreground again,I can continue to upload.

               

              this is my case:when i get a file path,i will do like this:

               

              1.first i will init a request ,wait it return a upload id.

              2.then i need to divide a big file(Maximum size for big file is 50 TB)into several small files(The size of each file is 5MB)to upload.I have a custom queue ,i will put these operations into this custome Queue  and  start a maximum of 5 tasks at a time.

              3.when all tasks completed,i will send a complete request to complete this transfer.

               

              but I have some problems:i test upload a 50MB file,it means that i will have a post request to init and 10 tasks to upload ,finally i need to send a post request to complete.

               

              scenario 1:

              1.when the app begin to run ,i click the beginupload button.

              2. and then i click the home to make my app enter background after a few seconds.

              result:   it will output logs and start new task when a task have completed,but it would stop suddenly after a few seconds, and stop output any logs,this situation happened frequently but not necessarily.

               

              scenario 2:

              1. when the app start to run ,i click the beginupload button

              2. i will wait all tasks complete and  i click the beginUpload button  once again to start a new transfer.

              3. then  i click the home to make the app enter background after a few seconds.

               

              result:   all tasks will be completed in background, it usually comes with a situation  that the  upload progress will be called back but i have not  restart my app until all task completed.

               

              I have tested it many times,and  i get a conclusion:once i have completed a upload,then i start a new transfer and make the app enter background,,all task always can be completed,but it usually comes with a situation  that the upload progress will called back,but i have not restarted my app until all task completed. If I upload it for the first time it always will stop and failed.

               

              Looking forward to your reply

                • Re: background multitasking upload
                  eskimo Apple Staff Apple Staff (12,475 points)

                  I’m not entirely sure I understand what you’re saying here, but I want to first make sure you’re testing this correctly.  Check out my Testing Background Session Code pinned post.

                  With regards your high-level issue, you wrote:

                  1. first i will init a request ,wait it return a upload id.

                  I would do this request using a standard URLSession, using a UIApplication background task to prevent the app from being suspended while that runs.  This ensures that the request either completes or fails promptly, avoiding the need for a (potential) background session resume between steps 1 and 2.

                  2. then i need to divide a big file(Maximum size for big file is 50 TB) into several small files (The size of each file is 5MB) to upload.I have a custom queue, i will put these operations into this custom Queue and start a maximum of 5 tasks at a time.

                  How are you managing this queue?  In memory?  Or on disk?

                  If it’s in memory then you’re going to need extra code because it’s possible that the system might terminate your app (and thus lose your memory state) while it’s suspended in the background.  If that happens it’ll relaunch your app when the current batch of tasks complete, and then you need to work out how to continue.

                  Also, is there any flexibility on the file size?  5 MB is too small.

                  Finally, running 5 tasks at a time is way too few.  Imagine you have to upload 1 GB.  Each upload cycle will upload 25 M, meaning you need to be resumed in the background 40 times.  The resume rate limiter will definitely be punishing you at that point.

                  In contrast, if you upped the file size to 20 MB and the task count to 50 — and these are both reasonable numbers — you could upload the whole file in one cycle.

                  3. when all tasks completed, i will send a complete request to complete this transfer.

                  This is another situation where you should explore using a standard session.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                    • Re: background multitasking upload
                      karisli Level 1 Level 1 (0 points)

                      Thank you very much for your reply and I'm sorry I didn't make myself clear

                      for your questions:

                      1. i run my app from xcode ,Do you think that's a reason that My app is still printing progress information after enter the background

                      (it seems to  print  lot of progress information  before the appDelegate method

                      application:handleEventsForBackgroundURLSession:completionHandler:

                      calleback  every time).

                       

                      2. How are you managing this queue?  In memory?  Or on disk?

                      i managed queue in memory,According to your advice, I will consider to save queue in disk.

                        • Re: background multitasking upload
                          eskimo Apple Staff Apple Staff (12,475 points)

                          i run my app from xcode, Do you think that's a reason that my app is still printing progress information after enter the background

                          Yes.  When you run from Xcode, you’re running with the debugger attached.  Having the debugger attached prevents your app from being suspended when it’s moved to the background.  As your app isn’t suspended, you continue getting progress events.

                          Share and Enjoy

                          Quinn “The Eskimo!”
                          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                          let myEmail = "eskimo" + "1" + "@apple.com"