URLSession is broken in iOS 18.4 RC Simulator

I'm seeing fully reproducible issues with URLSession on iOS 18.4 RC Simulator running from Xcode 16.3 RC. URLSession seems to get into a broken state after a second app run. The following sample succeeds in fetching the JSON on first app run but when the app is closed and ran again it fails with one of these errors:

  • Error: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
  • Error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."

I'm wondering if this something related to my OS setup or is this due to internal URLSession changes in iOS 18.4. Already submitted as FB17006003.

Sample code attached below:

import SwiftUI

@main
struct NetworkIssue18_4App: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var message: String = ""

    var body: some View {
        VStack {
            Text(message)

            Button("Try Again") {
                Task {
                    await fetch()
                }
            }
        }
        .task {
            await fetch()
        }
    }

    private func fetch() async {
        message = "Loading..."
        let url = URL(string: "https://poetrydb.org/title/Ozymandias/lines.json")!
        let session = URLSession.shared
        do {
            let response = try await session.data(from: url)
            print("Response: \(response)")
            message = "Success, data length: \(response.0.count)"
        } catch {
            print("Error: \(error)")
            message = "Error: \(error.localizedDescription)"
        }
    }
}
Answered by DTS Engineer in 831246022

Well, that’s not good. I ran your test and was able to immediately reproduce the problem.

Written by fastred in 777999021
Already submitted as FB17006003.

Thank you! I checked on your bug and the relevant folks have seen it.

Your bug mentioned HTTP storage, so I tweaked your code to use an ephemeral session and the problem went away.

let session: URLSession = {
    return URLSession(configuration: .ephemeral)
}()

Ephemeral sessions disable three standard things: cookie storage, the URL cache, and credential storage. So I tried creating a default session with those disabled:

let session: URLSession = {
    let config = URLSessionConfiguration.default
    config.httpCookieStorage = nil
    config.urlCache = nil
    config.urlCredentialStorage = nil
    return URLSession(configuration: config)
}()

Annoying, that didn’t fix the problem. So the ephemeral session is disabling something beyond those three standard things.

And that’s me out of obvious ideas )-: Clearly this is a bug that the URLSession folks will have to investigate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Seeing same issue on second app launch. Sometimes see the failures as “failed to parse response“ or “network connection was lost” errors.

Well, that’s not good. I ran your test and was able to immediately reproduce the problem.

Written by fastred in 777999021
Already submitted as FB17006003.

Thank you! I checked on your bug and the relevant folks have seen it.

Your bug mentioned HTTP storage, so I tweaked your code to use an ephemeral session and the problem went away.

let session: URLSession = {
    return URLSession(configuration: .ephemeral)
}()

Ephemeral sessions disable three standard things: cookie storage, the URL cache, and credential storage. So I tried creating a default session with those disabled:

let session: URLSession = {
    let config = URLSessionConfiguration.default
    config.httpCookieStorage = nil
    config.urlCache = nil
    config.urlCredentialStorage = nil
    return URLSession(configuration: config)
}()

Annoying, that didn’t fix the problem. So the ephemeral session is disabling something beyond those three standard things.

And that’s me out of obvious ideas )-: Clearly this is a bug that the URLSession folks will have to investigate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

One of my colleagues suggested that something might be broken in our HTTP/3 support. That gels with the symptoms you’ve described:

  • When you first run the app, it doesn’t know whether the server supports HTTP/3, so it defaults to HTTP/2.

  • As part of that exchange, it learns that the server supports HTTP/3 and remembers that.

  • The next time you run, it starts out with HTTP/3, which then fails.

Based on that, I tried the following tweak to your test:

var req = URLRequest(url: url)
#if targetEnvironment(simulator)
    req.assumesHTTP3Capable = false
#endif
let response = try await self.session.data(for: req)

With that, things starting behaving themselves.

Obviously this is less than ideal — HTTP/3 is your friend! — but it should tide you over for the moment.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@DTS Engineer Quinn, thank you for checking this so quickly. It makes sense why it works initially and only breaks on further request.

Do you know why this bug seems to occur only on the Simulator? Do real devices use a different URLSession implementation?

req.assumesHTTP3Capable does not solve the problem for me.

Things do work with an ephemeral session.

URLSession is broken in iOS 18.4 RC Simulator
 
 
Q