Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift OpenAPI Package Generator ClientMiddleware Protocol Never Conforms

When creating a new Authentication Middleware class that conforms to the ClientMiddleware protocol defined in the swift-openapi-runtime library, Xcode reports that the class does not conform to the protocol, even though the class implements the required function defined in the protocol.

I have tried using Xcodes generated protocol stubs, I have tried copying and pasting the function declaration from the protocol definition. Neither approache have resolved the error. The implemented codes is shown below:

import Foundation
import OpenAPIURLSession
import OpenAPIRuntime
import HTTPTypes

/// Injects an authorization header to every request.
struct AuthenticationMiddleware {
    
    /// The token value.
    var bearerToken: String

}

extension AuthenticationMiddleware: ClientMiddleware {
    
    func intercept(
        _ request: HTTPRequest,
        body: HTTPBody?,
        baseURL: URL,
        operationID: String,
        next: @Sendable (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)
    ) async throws -> (HTTPResponse, HTTPBody?) {
        var request = request
        request.headerFields[.authorization] = "Bearer \(bearerToken)"
        return try await next(request, body, baseURL)
    }
    
}

An image of the error within Xcode is shown below:

XCode error thrown for protocol noncomplience

like image 839
Andrew Paterson Avatar asked Sep 08 '26 11:09

Andrew Paterson


2 Answers

I have finally found the answer, after 5 days of going through everything.

The solution is to change one "Build Settings" setting named "Approachable Concurrency" from Yes to No (refer to the screenshot)

enter image description here

Or if you have VScode, open your project "project.pbxproj" file and change this here

enter image description here

If you have any questions or further additions please ask away.

like image 68
Anas Alhalabi Avatar answered Sep 11 '26 18:09

Anas Alhalabi


Just ran into the same thing. The currently accepted answer (turning off approachable concurrency) works, but if you prefer to keep that compiler flag on you can add @concurrent to the next argument, like so:

  public func intercept(
    _ request: HTTPRequest,
    body: HTTPBody?,
    baseURL: URL,
    operationID: String,
    next: @concurrent @Sendable (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)
  ) async throws -> (HTTPResponse, HTTPBody?) {
    ...
  }

This works by essentially "undoing" the default nonisolated(nonsending) feature of approachable concurrency and allowing next to be run on the global executor.

like image 45
igillis Avatar answered Sep 11 '26 19:09

igillis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!