Search Unity

UnityWebRequests on iOS sometimes get stuck indefinitely even with timeout set

Discussion in 'Scripting' started by nilsdr, Nov 26, 2020.

  1. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    been a while but I'm pretty sure the invalidation callback never once fired, going to try again just to make sure.
     
  2. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Ok, just ran our test case again to make sure, like so:

    Code (CSharp):
    1. @implementation UnityWebRequestDelegate
    2. - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error
    3. {
    4.     NSLog(@"NETWORK ERROR: %@", error);
    5. }
    6. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler
    7. {
    8.     NSLog(@"NETWORK OK: %@", response.URL);
    9.     [self handleResponse: response task: dataTask];
    10.     completionHandler(NSURLSessionResponseAllow);
    11. }
    12.  
    I get a network ok for the first 20 or so requests, then it just stops working. I never see NETWORK ERROR in the logs, so didBecomeInvalidWithError is not called
     
    halinc and altkey_ca like this.
  3. luke_avm

    luke_avm

    Joined:
    Mar 26, 2019
    Posts:
    10
    Saicopate, mae0510 and nilsdr like this.
  4. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    One possible workarounds to this issue is to add this line to UnityWebRequest.mm where the webOperationQueue is created:
    webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive;
     
  5. GoldARVR

    GoldARVR

    Joined:
    Oct 28, 2019
    Posts:
    6
    For everyone having this issue, I've replaced all my UnityWebRequest call by HttpClient call and it works. It was a lot of work and I had to learn a lot about HttpClient, but since there is no vision on the correction of this bug, I had to do it.

    And, well, HttpClient is really good. I don't know what are the pros of using UnityWebRequest since HttpClient can do the same if not better ?
     
  6. re-cheid

    re-cheid

    Joined:
    Apr 10, 2017
    Posts:
    34
    Thanks for the information.
    Is this just a temporary workaround, or is this the solution which will be integrated in a future release of Unity?

    //EDIT: I've tried this and it SEEMS TO FIX the problem! Thanks! Hope to see the fix in an official release soon, so we're able to use cloud builds again.
     
    Last edited: Jan 14, 2021
    halinc likes this.
  7. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    We use some Unity specific functionality like assetbundle caching, switching to httpclient isnt viable.
     
  8. Carlogeno

    Carlogeno

    Joined:
    Dec 11, 2016
    Posts:
    8
    I've changed all plugins code with HttpClient :-( ... this is an time expensive workaround... not a final solution :-(
     
  9. halinc

    halinc

    Joined:
    Feb 24, 2019
    Posts:
    32
    seems to work for me as well, thank you! added it in the method UnityCreateWebRequestBackend:
    Code (CSharp):
    1. webOperationQueue = [[NSOperationQueue alloc] init];
    2. webOperationQueue.name = @"com.unity3d.WebOperationQueue";
    3. webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive;
    looking forward to see this in an official bugfix update
     
    jgmakes likes this.
  10. ANTONBORODA

    ANTONBORODA

    Joined:
    Nov 16, 2017
    Posts:
    52
    Looking at the documentation for qualityOfService property, this doesn't seem to be a correct fix, rather a workaround.

    I can be mistaken because I can't fully understand why the problem happens in the first place, but setting a higher priority to a queue doesn't seem like a "correct" fix to me, rather it's hiding the underlying problem. Again, I can be wrong.
     
    Last edited: Jan 15, 2021
    apiotuch_unity and re-cheid like this.
  11. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    It seems that
    webOperationQueue.qualityOfService = NSQualityOfServiceUtility;
    is enough. I could not reproduce the issue after setting this quality of service.
     
  12. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    So what is causing it? Why does a functionality unrelated to networking stop it from working?
     
  13. apiotuch_unity

    apiotuch_unity

    Joined:
    Jun 28, 2019
    Posts:
    138
    We are currently testing more, however it seems like this fixed the issue for our team as well.
     
  14. re-cheid

    re-cheid

    Joined:
    Apr 10, 2017
    Posts:
    34
    Did anyone try this with iOS 14.2.1 (exclusive to iPhone 12 and iPhone 12 Pro)? Seems like one of our customers still has the problem

    //EDIT: not relevant, sorry, problem was somewhere else
     
    Last edited: Jan 19, 2021
  15. apiotuch_unity

    apiotuch_unity

    Joined:
    Jun 28, 2019
    Posts:
    138
    @re-cheid We updated everything to 14.3 (XR, MX Max, iPhone 7) and it works fine. Can the customer update their OS and see if there is still an issue?
     
  16. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    iOS 14.3 does not solve this issue.
    It seems the cause is that webOperationQueue does not fully satisfy the expectations of NSURLSession. Passing nil as delegate queue when creating session does solve the issue for me (the NSURLSession creates it's own queue in such case). I think that's the way to go with fixing this.
     
    nilsdr likes this.
  17. re-cheid

    re-cheid

    Joined:
    Apr 10, 2017
    Posts:
    34
    False alarm! it was a different issue with his environment.
     
    nilsdr likes this.
  18. FOKSlab

    FOKSlab

    Joined:
    Jun 27, 2017
    Posts:
    30
    Just FYI I used HTTPClient from ClaytonIndustry (as advised before in this thread) to fix my http request issue on iPhone (iOS 14.3), and it does the job... but I still have the issue on iPad OS 14.3 (iPad Pro) (InvalidServer error after sending the request : message "unknown" is returned ). Any clue why this fails on iPad OS ?

    EDIT : I forgot to say I upgraded my project to Unity 2020.2
     
  19. apiotuch_unity

    apiotuch_unity

    Joined:
    Jun 28, 2019
    Posts:
    138
    I meant our devices were all updated to 14.3 and using the webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive fix. We did not test with 14.2 or 14.2.1 because that would require us to downgrade the device OS which is more work than it is worth.
     
  20. jgmakes

    jgmakes

    Joined:
    Jan 10, 2019
    Posts:
    75
    @Aurimas-Cernius, thankfully your patch appears to work as an emergency fix for our product (!), and I'm hoping there will be a solid solution for the 2019 LTS branch and not only 2020 in the near term.

    I believe this is also the culprit of failures I've been tracking in Google Firebase's Firestore Unity SDK, which must also be based on the same underlying functionality (maybe
    dispatch_async_f()
    ). Same exact iOS 14.3 + ARFoundation setup as everyone else.
     
    Last edited: Jan 22, 2021
  21. FOKSlab

    FOKSlab

    Joined:
    Jun 27, 2017
    Posts:
    30
    I replaced (again :'( ) my web request, fixing it to use the UnityWebRequest instead of HttpClient (using NSQualityOfServiceUtility) and it works on windows / iOS / iPadOS ... but when I try to access a local server (Apache) from iPadOS (windows & iOS are OK) it returns a [Connection Error] ("No internet Connection" error message).
    I cannot understand what is different from my iPhone on my iPad.

    Have you ever try local access with your UnityWebRequest (ARfoundation app) ? If so did it work on iPad OS ? if not have you found a way to make it work on iPad OS 14.3 ?
     
  22. gezapp

    gezapp

    Joined:
    Apr 18, 2014
    Posts:
    20
    Thank you all :)
     
  23. jgmakes

    jgmakes

    Joined:
    Jan 10, 2019
    Posts:
    75
    @Aurimas-Cernius,

    Might this be related to bugs popping up like this or this?

    Have you filed a bug officially with Apple? That would be super helpful and I imagine a report coming from a platform like Unity would carry a lot more weight. I'd guess Unity users constitute a significant percentage developers using ARKit, and thus apps hitting this issue.

    Thanks for continuing to look into this!
     
    developer_unity224 likes this.
  24. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    You’re using the .background QoS and the device is in a condition that disallows that QoS (low power mode, extremely hot, and so on).

    Could this not be it? Webrequests are queued with low priority, causing them to be stalled when the device decides it needs to take it easy for a bit (i.e., under heavy load like when using ARKit). I would then expect the same kind of behaviour when rendering really complex scenes, even without AR

    This is admitedly a baseless guess
     
  25. jgmakes

    jgmakes

    Joined:
    Jan 10, 2019
    Posts:
    75
    Makes sense that it would get less priority if we are (or Unity is) asking for less priority by default, and why the
    NSQualityOfServiceUtility
    change would help. I can't tell if you're explaining or justifying the behavior.

    Even if it's a background task that gets dropped, it clearly needs to get dropped with a failure or cancellation message of some kind.

    Otherwise we could add modal prompts to all our web requests:
    "Your [bank transaction] may or may not have finished. If it didn't and you try again, it may or may not have the same result. You could quit and try again, but no guarantees there either. Take this as a life lesson and reflection on uncertainty of life. Access your zen. Breathe deeply. Give a stranger a hug."
     
    Last edited: Jan 22, 2021
  26. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    It's not the queue that stops executing the tasks, it's NSURLSession that stops working, maybe related to handling of taks by the queue (or due to some internal logic dependent on the queue). After requests stop working, you can still submit taks to queue and they do get executed, but the requests don't work.
    Hence the better fix is to not pass the queue when creating NSURLSession, then it will create it's own queue and doesn't stop working.
     
    carldevelopsforcoffee likes this.
  27. jgmakes

    jgmakes

    Joined:
    Jan 10, 2019
    Posts:
    75
    Thanks for the info. This is above my pay grade :) Clearly you'd file a MUCH more helpful iOS bug than me ;)

    Everyone else here is doing some patchwork on UnityWebRequest.mm or refactoring to remove the dependency on UWR entirely. We're all just trying to get our apps working again. Not a wonderful end solution for the Unity platform and community (or for the iOS ecosystem at large).
     
  28. thesleeper

    thesleeper

    Joined:
    Sep 3, 2014
    Posts:
    14
    Thank you for all, the light you guys have all shed on this thread. Working with ARFound/Kit and IOS 14.3 and the "
    webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive;" hack seems to be working.

    Will keep an eye out for any developments to this issue.
     
  29. thesleeper

    thesleeper

    Joined:
    Sep 3, 2014
    Posts:
    14
    doing a quick search for more solutions brings me to this page (fogzbugz.unity3d) which one of the responses from the unity dev team says:

    can anyone confirm this? but my project is in unity 2019.4.16f1, can anyone suggest any other solutions aside from the qualityOfService hack?
     
  30. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    The solution is not pass nil instead of queue when creating session. The queue is then used only for uploads.
     
  31. Archi_16

    Archi_16

    Joined:
    Apr 7, 2017
    Posts:
    87
    What about unity 2018.4.23.
    i dont have the UnityWebRequest.mm file.
    What i should fix in that case?
     
  32. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Is 2018.4 affected too?
    The thing is that 2018.4 uses entirely different implementation (older, now deprecated iOS APIs). According the reports I was under the impression that this is 2019.4+ bug.
     
  33. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    Yes I'm experiencing it in 2018.4.13
     
  34. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Yikes, thanks for reporting. I'll look into it.
    Most likely the fix is to change the queue quality to utility. In 2018.4 I believe the file to modify is WWWConnection.mm.
     
    J_P_ likes this.
  35. Archi_16

    Archi_16

    Joined:
    Apr 7, 2017
    Posts:
    87
    Yeap. IOS 14 broke everything :D thats why I dont like iOS.
     
    Last edited: Feb 6, 2021
  36. Archi_16

    Archi_16

    Joined:
    Apr 7, 2017
    Posts:
    87
    Got it.

    For those who using unity 2018.4.*
    add this in file WWWConnection.mm at line after 392
    webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive;

    Must help :)
     
    J_P_ likes this.
  37. thesleeper

    thesleeper

    Joined:
    Sep 3, 2014
    Posts:
    14
    HI all, the above mentioned method (webOperationQueue hack) works with IOS 14.3, however on iPad IOS14.4, the issue still remains. does anyone have any light to shed on the situation? or does anyone have a similar experience with IOS14.4
     
  38. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Try passing nil when NSURLSession is created instead of webOperationQueue.
     
  39. thesleeper

    thesleeper

    Joined:
    Sep 3, 2014
    Posts:
    14
    hi Aurimas-Cernius, is there an API or documentation i can refer to regarding passing nil? to be honest im not entirely sure where i should be applying that fix.

    Edit: is this correct? :
    UnityWebRequest.mm : Line 290

    Code (CSharp):
    1. unityWebRequestSession = [NSURLSession sessionWithConfiguration: config delegate: delegate delegateQueue: webOperationQueue];
    becomes

    Code (CSharp):
    1. unityWebRequestSession = [NSURLSession sessionWithConfiguration: config delegate: delegate delegateQueue: nil];
    Thank you in advance for your assistance!
     
    Last edited: Feb 11, 2021
    RI-AR likes this.
  40. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Yes, that is correct, you have to pass nil as delegateQueue.
     
  41. Juanola_

    Juanola_

    Joined:
    Sep 29, 2015
    Posts:
    38
    Hello!

    So, I had the same problem and solved it with the webOperationQueue.qualityOfService = NSQualityOfServiceUserInteractive; hack. Im using Unity 2019.4.14f.

    The thing is, I have my CI process integrated with Unity Cloud. Unfortunately, I cannot build using this hack on Unity Cloud. Is there something that can be done?

    On the other hand, is there a Unity version that has this hacked solved and integrated?

    Thanks!
     
  42. re-cheid

    re-cheid

    Joined:
    Apr 10, 2017
    Posts:
    34
    here's the issue tracker link for this, you can follow the fix status there:
    https://issuetracker.unity3d.com/is...61.1517177904.1613124733-622603087.1593029366
     
  43. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
  44. Midnight-Walker

    Midnight-Walker

    Joined:
    Mar 6, 2015
    Posts:
    3
    I have tried everything but nothing seems to fix issue with 2019.4.20f1. Everything was fine with 2019.4.19f1. So... It was fixed before 19f1? And now it's broken again and I cannot find the way to fix it.
     
  45. hugogfadams

    hugogfadams

    Joined:
    Jul 27, 2020
    Posts:
    6
    Hi, I also have found this bug. I'm using 2019.4.5 and ARFoundation.

    I have only noticed it happening when building from Xcode, It usually occurs within a couple of minutes. Once I'm running the app off the phone and not connected to Xcode I haven't seen the bug occur. I assumed it was something to do with Xcode's output or debugger system. Also I did some quick testing with the same version of the project, the bug doesn't seem to occur as much if Development Build is ticked.
     
  46. thesleeper

    thesleeper

    Joined:
    Sep 3, 2014
    Posts:
    14
    Hi, unfortunately this did not work.

    I've moved on to 2020.2.4f1, however there are a whole new slew of issues with that version that aren't related to this topic. Just a word of caution for everyone experiencing the same issues.
     
  47. thesleeper

    thesleeper

    Joined:
    Sep 3, 2014
    Posts:
    14
  48. re-cheid

    re-cheid

    Joined:
    Apr 10, 2017
    Posts:
    34
  49. Midnight-Walker

    Midnight-Walker

    Joined:
    Mar 6, 2015
    Posts:
    3
    I just tried with that version. No luck here. Does not work with 2019.4.21f1 even thought with 2019.4.19f1 everything is fine.
     
  50. nlacroixAOD

    nlacroixAOD

    Joined:
    Jul 20, 2018
    Posts:
    20
    @Midnight-Walker Does building as a 'Development Build' make the issue go away or reduce it? Wondering if we're getting the same thing. We had the same issue in this thread before with 2019.4.5 and it seemed to be resolved after doing these fixes but we're now getting similar errors again even with 2019.4.21 (which has all the fixes mentioned here).