Bug:
I'm consistently getting error code -1009 "The Internet connection appears to be offline." errors when making URLSession requests in an Apple Watch extension on an Apple Watch Series 3 when connected to the Internet only via LTE.
Steps to Reproduce:
Expected Behavior:
The request manages to reach the destination.
Observed Behavior:
The request fails immediately with error code -1009 "The Internet connection appears to be offline."
Code Sample:
let config = URLSessionConfiguration.ephemeral
let sesh = URLSession(configuration: config)
let url = URL(string: "https://google.com")!
sesh.dataTask(with: request) { (_, _, error) in
print(error)
}.resume()
Restart your device. Open your Settings app and tap Network & internet or Connections. Depending on your device, these options may be different. Turn Wi-Fi off and mobile data on, and check if there's a difference. If not, turn mobile data off and Wi-Fi on and check again.
NOPE: SEE UPDATE #3 BELOW: The crucial missing element: you must set the waitsForConnectivity
flag on your session configuration to true
.
let config = URLSessionConfiguration.ephemeral
config.waitsForConnectivity = true
let sesh = URLSession(configuration: config)
let url = URL(string: "https://google.com")!
sesh.dataTask(with: request) { (_, _, error) in
print(error)
}.resume()
If you do not set that flag, the requests fail immediately because LTE access isn't available instantly but only after the briefest of delays. Setting this flag to true makes the requests work. In my testing there even seems to be no appreciable difference in timing between enabling the waitsForConnectivity
over LTE and making the same request without enabling waitsForConnectivity
but conducted over WiFi, almost like the waiting period enabled by waitsForConnectivity
in some scenarios is a next-turn-of-the-runloop kind of situation.
Update #1
I am unable to make any requests over LTE. When waitsForConnectivity
is set to true
, the requests just timeout according to the timeout properties of the session config. When waitsForConnectivity
is false
, the requests fail immediately. I'll update my question and answer when I have more information. I'm waiting on a response from an Apple TSI request which usually takes several days.
Update #2
Adding to the mystery, the same sample code runs fine over cellular on two other developers' hardware. I know that my hardware is good because Apple's apps fun fine over LTE on it (phone calls rolling down the highway with nothing but my watch in the car). So there's something really fishy going on. I've asked Apple DTS to look into this, and they can't reproduce the issue either. I'll be following up with them as soon as I can.
Update #3
Sometime in the intervening weeks after I last updated this post, cellular requests started working in my apps. I didn't change anything about my watch, no software updates, no resets, nothing. I didn't even recompile the code; the same build is still on my watch as previously. It just started working as expected, same as it did on other developers' devices.
The only thing strange I noticed is that I got three, back-to-back, identical SMS messages from AT&T notifying me that my Apple Watch is now linked to my iPhone number. Which is strange, because that linkage supposedly occurred the night I unboxed my phone, not two months later. I have no idea if this is related to my issue. All I know is that cellular requests are now working.
I had the same problem but was developing an App for the iPhone. This is what finally solved the problem. I set the configuration objects property:
config.allowsCellularAccess = true
This is very confusing, because the Apple documentation states that this property is set to true by default... but in my case it was not. Also, even though I am using "background tasks," and they are always meant to wait for connectivity, I also set waitsForConnectivity = true
, too, just in case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With