How do I refer to a function that may not exist?

I tried to gatekeep with conforms(to:) and putting my function as a requirement of a protocol, and it compiles fine if the conformance is there, but it won’t compile without that conformance. The whole point is for that conformance to be an optional way to provide a default, so I need it to be able to ignore it if it doesn’t exist. In my screenshot you’ll see where it’s erroring out. If I uncomment my conformance extension it compiles just fine.

Try calling it through existential:

        var impliedFont: UIFont?
        if let provider = (UIFont.self as Any.Type) as? UIViewRepresentablePreferredFontProvider.Type {
            impliedFont = provider.preferredFont(forUIViewRepresentableWithTextStyle: style)
        }

Instead of .conforms(to:), you can use an as? cast.

1 Like

That didn’t really work either. I just gave up and added it as an instance method on my AppDelegate.

I tested both suggested approaches and both worked for me. The second being:

    if let provider = UIFont.self as Any.Type as? UIViewRepresentablePreferredFontProvider.Type {
        ....

FTM, the first "as Any.Type" is to avoid the warning in both approaches.

I had missed this reply earlier. This looks good, but the UIFont includes the size, so I’d like it to take a parameter (I’m ignoring the parameter in my proof of concept, but eventually it would matter.)

That warning was what I meant with “didn’t really work” so I think this could be the missing piece. Thanks!

Hi! Personally I don't think that's a good design, but maybe I'm missing a peace of the puzzle.

In my opinion, you should use the protocol to enforce the usage of the method and potentially have another protocol extending the first one and providing a default implementation for the method. Hence you are sure that you are working with an object that has the requirement and give an extra option to your user to add a default implementation; because down casting removes polymorphisme and makes your code more tightly coupled to the specific types.

So it would be something like that :

protocol MyConformance {
    func myMethod(...)...
}

protocol MyConformanceDefaultImplementation: MyConformance {}
extension MyConformanceDefaultImplementation {
    func myMethod(...){
        // default implementation 
    }
}

So in any case you conform to MyConformance and eventually to MyConformanceDefaultImplementation instead if you want a default implementation.

It probably isn’t. I don’t know what the proper way to do this kind of thing would be. I wouldn’t have to do this at all if Apple would just let me get a UIFont from the SwiftUI Environment to pass to the custom controls with UIKit. Or really if SwiftUI.Text would not clip custom fonts in the first place. I opened a bug for that last bit, because it really shouldn’t clip to its frame without .clipped() modifying it.