HTTP/3 in your App

This thread has been locked by a moderator; it no longer accepts new replies.

This content has now moved to TN3102: https://developer.apple.com/documentation/dts-technotes/tn3102-http3-in-your-app

HTTP/3 is a major new feature in iOS 15. While you wait for your server to add support for it, here’s how you can test it today in your app:

  1. Install iOS 15.0 beta on a test device (HTTP/3 is not supported in the simulator).
  2. In Settings > Developer, under the Networking group, enable HTTP/3.
  3. Using Xcode 13.0 beta, create a new project from the iOS > App template. Set the Interface popup to Storyboard and the Language popup to Swift.
  4. Change ViewController.swift to the code shown below.
  5. In Main.storyboard add a Test button and wire it up to testAction(_:).
  6. Run the app on your device.
  7. Tap your Test button.

Your app will print something similar to:

task will start, url: <# Your H3 URL Here #>
protocols: ["h3-29"]
task finished with status 200, bytes 703

The protocols array shows the protocol used for each HTTP transaction. In this case there was a single HTTP/3 transaction. In some cases you may see the protocol being returned as (h2) or even (http1.1). If this is the case then run the transaction again, as URLSession may need to apply the H3 service discovery option that your server sent back on the previous HTTP response.

Service discovery for HTTP/3 is performed in one of the following ways: the recommended approach is to configure your DNS server to advertise the HTTPS resource record for alpn="h3,h2". You should also configure your server to respond back with the Alt-Svc header that advertises HTTP/3. For example, Alt-Srv: h3=":443"; ma=2592000. To attempt to use HTTP/3 on the first transaction, try using the assumesHTTP3Capable property on the URLRequest being used to execute the dataTask in URLSession. For cases where HTTP/3 is not supported on the server, or over the network, you will see the protocol fall back to (h2) or (http1.1). For more information on this, please see the WWDC session for Accelerate networking with HTTP/3 and QUIC.

NOTE: Servers that support HTTP3 should be based on Draft 29 or later.

If you experience issues while debugging your network transactions, take a look at these requests in the Network Instruments tool to debug what you are seeing being sent back from your server. For more on this, see the WWDC session for Analyze HTTP traffic in Instruments.

import UIKit

class ViewController: UIViewController, URLSessionDataDelegate {

    private var session: URLSession!
    
    @IBAction
    private func testAction(_ sender: Any) {
        if self.session == nil {
            let config = URLSessionConfiguration.default
            config.requestCachePolicy = .reloadIgnoringLocalCacheData
            self.session = URLSession(configuration: config, delegate: self, delegateQueue: .main)
        }

        let urlStr = "<# Your H3 URL Here #>"
        let url = URL(string: urlStr)!
        var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)
        request.assumesHTTP3Capable = true
        print("task will start, url: \(url.absoluteString)")
        self.session.dataTask(with: request) { (data, response, error) in
            if let error = error as NSError? {
                print("task transport error \(error.domain) / \(error.code)")
                return
            }
            let response = response as! HTTPURLResponse
            let data = data!
            print("task finished with status \(response.statusCode), bytes \(data.count)")
        }.resume()
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
        let protocols = metrics.transactionMetrics.map { $0.networkProtocolName ?? "-" }
        print("protocols:", protocols)
    }
}
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Change history:

  • 16th June 2021 - Initial Post.
Boost
HTTP/3 in your App
 
 
Q