Created
December 9, 2018 20:39
-
-
Save joseph-elmallah/6eb8c332a4465da715e5b4a4c89b8854 to your computer and use it in GitHub Desktop.
A decoupled way to propagate URL opening in an iOS app over the Responder chain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Conforming to this protocol allows for URL handling | |
protocol URLHandler { | |
/// Handle a URL | |
/// | |
/// - Parameter url: The propagated url | |
/// - Returns: The handled status | |
func handleURL(_ url: URL, options: [UIApplication.OpenExternalURLOptionsKey : Any], completionHandler completion: ((Bool) -> Void)?) | |
} | |
// MARK: - Error Propagation | |
extension UIResponder { | |
/// Propagates a URL through the responder chain. | |
/// | |
/// - Parameters: | |
/// - url: The URL to propagate | |
/// - options: A dictionary of options to use when opening the URL. For a list of possible keys to include in this dictionary, see URL Options. | |
/// - completion: The block to execute with the results. Provide a value for this parameter if you want to be informed of the success or failure of opening the URL. | |
func propagateURL(_ url: URL, | |
options: [UIApplication.OpenExternalURLOptionsKey : Any] = [:], | |
completionHandler completion: ((Bool) -> Void)? = nil) { | |
// Check if we have a next, otherwise return `false` to indicate that the operation failed | |
guard next != nil else { | |
completion?(false) | |
return | |
} | |
// Check if the next responder can handle URLs | |
guard let urlHandler = next as? URLHandler else { | |
// If not then carry on the propagation of the URL | |
next?.propagateURL(url, options: options, completionHandler: completion) | |
return | |
} | |
// Ask the Next to handle the URL | |
urlHandler.handleURL(url, options: options) { [weak self] (status) in | |
if status == false { | |
// If the next failed to handle the URL, continue the propagation of the URL | |
self?.next?.propagateURL(url, options: options, completionHandler: completion) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment