Why doesn’t getAPI() show up in autocomplete despite having a default implementation in a protocol extension?

I’m working on a project in Xcode 16.2 and encountered an issue where getAPI() with a default implementation in a protocol extension doesn’t show up in autocomplete. Here’s a simplified version of the code:

import Foundation

public protocol Repository {
    func getAPI(from url: String?)
}

extension Repository {
    public func getAPI(from url: String? = "https://...") {
        getAPI(from: url)
    }
}

final class _Repository: Repository {
    func getAPI(from url: String?) {
        // Task...
    }
}

let repo: Repository = _Repository()
repo.getAPI( // Autocomplete doesn't suggest getAPI()

I’ve tried the following without success: • Clean build folder • Restart Xcode • Reindexing

Is there something wrong with the code, or is this a known issue with Xcode 16.2? I’d appreciate any insights or suggestions.

Answered by DTS Engineer in 822297022
Written by Journey36 in 822167022
I expect it to autocomplete as getAPI() [without any arguments]

Oh, right, I missed that subtlety. Thanks for the correction.

So, yeah, the behaviour in your first example is understandable but I think you could argue that Xcode should do better.

It’s understandable because this:

let repo: Repository = _Repository()

means that repo is of type any Repository, and only getAPI(from:) is a requirement of the Repository protocol. However, anything that conforms to Repository will also gain the default argument version, so it’d be nice if Xcode included that. Feel free to file a bug about that. And if you do file a bug, please post your bug number.

Having said that, you can get what you want by changing the extension to this:

extension Repository {
    
    public func getAPI() {
        getAPI(from: "https://...")
    }
}

Personally, I think that’s clearer in this case, but perhaps that’s not the case in your real sourcebase.

Share and Enjoy

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

I does on my machine. Specifically, I’m running Xcode 16.2 on macOS 15.2. I created a new project from the macOS > Command Line Tool target and pasted your code into it. Here’s what I see:

If you create a new project and try it there, does it work there?

Share and Enjoy

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

@DTS Engineer Thank you for answering my question 😆

I expect it to autocomplete as getAPI() when I press the return key in the state shown in the screenshot you provided. However, it always autocompletes as getAPI(from: <#String?#>). The same behavior occurs even in a new project.

If I modify the existing code to the following and execute it, the autocomplete should behave the same. However, I’m not sure what difference is causing it not to work:

import Foundation

public protocol Repository {
    func getAPI(from url: String?)
}

extension Repository {
    public func getAPI(from url: String?) {
        getAPI(from: url)
    }
}

final class _Repository: Repository {
    func getAPI(from url: String? = "https://...") {
        // Task...
    }
}

let repo = _Repository()
repo.getAPI( // Autocomplete suggest getAPI() first.
Accepted Answer
Written by Journey36 in 822167022
I expect it to autocomplete as getAPI() [without any arguments]

Oh, right, I missed that subtlety. Thanks for the correction.

So, yeah, the behaviour in your first example is understandable but I think you could argue that Xcode should do better.

It’s understandable because this:

let repo: Repository = _Repository()

means that repo is of type any Repository, and only getAPI(from:) is a requirement of the Repository protocol. However, anything that conforms to Repository will also gain the default argument version, so it’d be nice if Xcode included that. Feel free to file a bug about that. And if you do file a bug, please post your bug number.

Having said that, you can get what you want by changing the extension to this:

extension Repository {
    
    public func getAPI() {
        getAPI(from: "https://...")
    }
}

Personally, I think that’s clearer in this case, but perhaps that’s not the case in your real sourcebase.

Share and Enjoy

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

Why doesn’t getAPI() show up in autocomplete despite having a default implementation in a protocol extension?
 
 
Q