Search code examples
swiftprotocolsuiapplication

Swift: Unable to make UIApplication conform to my protocol


I'm trying to make UIApplication conform to the following protocol:

protocol URLOpenerProtocol {
    func open(_ url: URL, completionHandler: ((Bool) -> Void)?)
}

I've added the following extension:

extension UIApplication: URLOpenerProtocol {}

However, I am getting a conforming error.

Given the UIApplication already has the following method on it:

UIApplication.shared.open(_ url: URL, completionHandler: ((Bool) -> Void)?)

why won't this conform? The two seem to be indentical to me...

Error is as follows:

Type UIApplication does not conform to protocol URLOpenerProtocol


Solution

  • The actual open method in UIApplication is declared like this with 3 parameters, and the second and third ones happen to be optional (source):

    func open(
        _ url: URL,
        options: [UIApplication.OpenExternalURLOptionsKey : Any] = [:],
        completionHandler completion: ((Bool) -> Void)? = nil
    )
    

    UIApplication has no two-parameter method with this signature:

    func open(_ url: URL, completionHandler: ((Bool) -> Void)?)
    

    It only has the three-parameter one. Therefore, it does not conform to your protocol.

    You should add the options parameter into your protocol too, so that UIApplication can conform to it, and I would suggest that you add a protocol extension with the two-parameter version:

    protocol URLOpenerProtocol {
        func open(_ url: URL,
                  options: [UIApplication.OpenExternalURLOptionsKey : Any],
                  completionHandler: ((Bool) -> Void)?)
    }
    
    extension URLOpenerProtocol {
        func open(_ url: URL,
                  completionHandler: ((Bool) -> Void)?) {
            open(url, options: [:], completionHandler: completionHandler)
        }
    }