This is an interesting article about using Swift pattern matching for routing deeplink URLs.
The majority of URL routing libraries use a pattern syntax that can match each element of a URL's path in one of three ways:
- Equality: Path element must match the pattern expression.
- Value-binding: Path element can be anything at all and will be made available in a parameters dictionary.
- Wildcard: Path element can be anything at all, and will be discarded.
There are a few reasons I don't much like this approach:
- The pattern matching is abstracted away using special syntax.
- The parameter name userId is repeated and stringly typed, so it's susceptible to typos.
- parameters["userId"] should never be nil, but the compiler doesn't know that, so we must force unwrap or add a guard statement.
As it happens, Swift's built-in pattern matching can be used for each of the three pattern types.
It proceeds to walk through the design process of a few abortive approaches and ends up with the URLPatterns library here.
I prefer this approach to the approach taken by most URL routing libraries for a few reasons:
- It's simple to bypass URLs and open a deeplink directly, e.g. by calling DeepLinker.open(.Home).
- The pattern-matching code is no longer in a third-party library, which makes it easier to debug.
- The pattern-matching code leverages Swift's built-in pattern-matching, which means it can be customized and extended.
- The pattern-matching and routing processes are separated into two steps. This provides an override point if needed…
Neat! For even more niftiness, check out the Generator approach in URLs and Pattern Matching mentioned in the comments.
And while we’re discussing routing, if you want something more conventional, this looks like a good choice:
JLRoutes: "URL routing library for iOS with a simple block-based API."
- Simple API with minimal impact to existing codebases.
- Parse any number of parameters interleaved throughout the URL.
- Wildcard parameter support.
- Seamlessly parses out query string and fragment parameters and passes them along as part of the parameters dictionary.
- Route prioritization.
- Scheme namespaces to easily segment routes and block handlers for multiple schemes.
- Return NO from a handler block for JLRoutes to look for the next matching route.
- Optional verbose logging.
- Pretty-print the whole routing table.
- No dependencies other than Foundation.
Looks like a sweet drop-in to handle just about everything you'd want, that!