URLSessionDataTask very slow on watchOS

I am using URLSessionDataTask on watchOS 4, tested on Xcode 9 Simulator and Apple Watch Series 2 42mm. This is the code:


let ts = Date()

let task = urlSession.dataTask(with: urlRequest, completionHandler: {
  [weak self] data, response, error in

  self?.log(executionSince: ts, "URLSessionDataTask completed")
  ....
  })
}


The network request executes in 20-50ms, I checked and re-checked using network proxy.

However, the time difference between calling the dataTask and the moment it calls its completion handler is 6-10 seconds. That sounds pretty ludicrious and I'm not sure what I can do to improve it. This can't be normal behavior...


I have looked around the forums and found this thread from 2015, which I don't know what to do with.

Accepted Reply

To help anyone encountering this. I sent a DTS ticket and received a very good response on this.


Summary:

- watchOS will almost always have slightly slower response than iOS, since it always tries to go first through iPhone if it's reachable, then known wi-fi if not. Lastly it tries LTE on Series 3.

- on the actual device, the completion handler is called in (at least) expected timeframe

- on the watchOS simulator, the completion handler is abnormally slow (mentioned 6-10s) and I have filed a bug report


Hope this helps.

Replies

Does this happen for all requests, regardless of the URL? Or are you seeing it for some specific URLs?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Happens for every request, times vary wildly: 6, 8, 12, 15s.


I switched to using URLSessionDelegate to see more closely what's happening and this the result:


START: 2017-09-27 09:46:06 +0000

RESPONSE: 2017-09-27 09:46:13 +0000

DATA: 2017-09-27 09:46:16 +0000


START = task.resume()

RESPONSE = urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void)

DATA = urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Swift.Error?)


Thus the majority of the time is before the HTTPResponse callback is received.


Trying the identical code on iOS (either device or Simulator) with same wifi network connection has almost no delays at all (iPhone 6s, iPhone 7 Plus).

Same network, same API call, on iOS:


START: 2017-09-27 10:06:06 +0000

RESPONSE: 2017-09-27 10:06:06 +0000

DATA: 2017-09-27 10:06:06 +0000

Here's a Demo project that shows the problem.


Run it in iOS Simulator, then in the watchOS Simulator. You will see the different in response time is 100x

Here's a Demo project that shows the problem.

That’s a pretty big demo. Any chance you can cut it down into something more manageable? That’ll help in two ways:

  • The act of cutting it down might reveal what’s causing the delay.

  • If not, you’ll have a much smaller project for other folks to look at.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Sure, here it is. All the relevant code is in one file per platforms.


Thanks for looking into this.

To help anyone encountering this. I sent a DTS ticket and received a very good response on this.


Summary:

- watchOS will almost always have slightly slower response than iOS, since it always tries to go first through iPhone if it's reachable, then known wi-fi if not. Lastly it tries LTE on Series 3.

- on the actual device, the completion handler is called in (at least) expected timeframe

- on the watchOS simulator, the completion handler is abnormally slow (mentioned 6-10s) and I have filed a bug report


Hope this helps.

and I have filed a bug report

And, just for the record, that bug number 34810194.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

On the DTS ticket, it was mentioned:


"on the actual device, the completion handler is called in (at least) expected timeframe"


Did they specify what the expected timeframe was? In my tests, on an actual device (Apple Watch Series 3 with LTE), I'm having the same 3-5 second response time as on the Apple Watch Simulator.


The watch app I am writing is one that I’d like to work when you are away from your phone (disconnected), but where the watch on LTE or Wifi. A 3-6 second delay on every service call is quite a long time to wait when NSData returns the same call on the Apple Watch within 200-300ms. The web API call is made when a user clicks on the button and makes a selection so I can’t effectively make the call in the background prior to them clicking their option (the number of options is 66).


My hope is that this 3-5 second time can be decreased to the regular speed of NSData of around 200-300ms (in reference to my API test that responds in the 200-300ms time in a browser).


Thanks,


John

If forgot this in my original post. I always get the return time of 3-5 seconds in all of the following scenarios:


  1. Physical Apple Watch Series 3 with Cellular connected to Phone connected to WIFI
  2. Physical Apple Watch Series 3 with Cellular connected to Phone connected to LTE
  3. Physical Apple Watch Series 3 with Cellular connected to WIFI, disconnected from Phone
  4. Physical Apple Watch Series 3 with Cellular connected to LTE, disconnected from Phone


There is no scenario using UrlSession where the response time is in the milliseconds like NSData (connectwith url).