I have a function on my class that used to take default parameters, but because I'm making a protocol instead - to facilitate mocking network calls - my function can no longer take default parameters. So I thought I would do an extension of my function with several functions that provide the same function call signatures as used before, so that I don't have to change the calls that are made in numerous applications. (This class is part of a Swift Package). The problem is that classes that call the functions in my implementing class cannot see those protocol extension functions. Here is my protocol:
protocol WebService<EndPointType> {
associatedtype EndPointType
func request<ResponseType: Decodable>(_ endPoint: EndPointType, _ params: Parameters?, _ moreParams: Parameters?, codable: Codable?) async throws -> ResponseType
}
extension WebService {
public func request<ResponseType: Decodable>(_ endPoint: EndPointType) async throws -> ResponseType {
return try await request(endPoint, nil, nil, codable: nil)
}
}
(There would eventually be more of these extension functions if this would work).
Here is the relevant part of my implementing class:
public class Router<EndPointType: EndPoint>: WebService {
public func request<ResponseType>(_ endPoint: EndPointType, _ params: Parameters?, _ moreParams: Parameters?, codable: Codable?) async throws -> ResponseType where ResponseType : Decodable {
...
And here is an attempt to call the extension function that is failing:
let appStatusResponses: [AppStatusResponse] = try await router.request(.getStatus)
This fails to compile with the message: "Missing arguments for #2, #3, 'codable' in call".
If I move the extension function into my implementing class, it compiles.
Why isn't the protocol extension function visible to the calling class? It is visible in the implementing class, but not in the class that calls the implementing class. I have verified the non-visibility in one and the visibility in the other by the auto-suggest in Xcode.
Any tips would be appreciated.
Thank you.
Rob's mention of the public modifier was the main thing needed. In retrospect, that should have been obvious, but since this protocol is being used by another package in the same codebase, I thought it would have access already. Also I made a mistake early by applying the public modifier to the protocol but not to the extension. Here is the final protocol with extension:
public protocol WebService<EndPointType> {
associatedtype EndPointType
func request<ResponseType: Decodable>(_ endPoint: EndPointType, _ params: Parameters?, _ moreParams: Parameters?, codable: Codable?) async throws -> ResponseType
}
public extension WebService {
func request<ResponseType: Decodable>(_ endPoint: EndPointType) async throws -> ResponseType {
return try await request(endPoint, nil, nil, codable: nil)
}
func request<ResponseType: Decodable>(_ endPoint: EndPointType, codable: Codable?) async throws -> ResponseType {
return try await request(endPoint, nil, nil, codable: codable)
}
func request<ResponseType: Decodable>(_ endPoint: EndPointType, _ params: Parameters?) async throws -> ResponseType {
return try await request(endPoint, params, nil, codable: nil)
}
func request<ResponseType: Decodable>(_ endPoint: EndPointType, _ params: Parameters?, codable: Codable?) async throws -> ResponseType {
return try await request(endPoint, params, nil, codable: codable)
}
}