In iOS, deep linking actually includes URL jump methods such as URL Scheme, Universal Link, notification, or 3D Touch. Application scenarios such as common notifications, social sharing, payment, or clicking a specific link in the webView to open it in the app and jump to the corresponding native page.
The most commonly used and most commonly used is to implement deep linking through Custom URL Scheme. In application:openURL:sourceApplication:annotation or application:openURL:options introduced after application:openURL:sourceApplication:annotation or iOS9, the corresponding business logic is executed by processing the URL. Generally, simply compare strings. However, if there are many corresponding scenarios for URL jumps, it will be less simple to develop and maintain. The best practice for this is to introduce routers to unify all portals that may exist.
One of the methods introduced here to use router to organize the entry is from the open source project with kickstarter-ios, which is developed purely in swift and has developers' video sharing.
In the project, all entry points that support jumping through URLs are defined as a case by Navigation enum.
public enum Navigation { case checkout(Int, ) case messages(messageThreadId: Int) case tab(Tab) ... }
All URL templates are listed in the allRoutes dictionary, as well as the corresponding parsing functions.
private let allRoutes: [String: (RouteParams) -> Decode<Navigation>] = [ "/mpss/:a/:b/:c/:d/:e/:f/:g": emailLink, "/checkouts/:checkout_param/payments": paymentsRoot, "/discover/categories/:category_id": discovery, "/projects/:creator_param/:project_param/comments": projectComments, ... ]
In the match(_ url: URL) -> Navigation function, traverse allRoutes to match the incoming url. The specific process is: within the match function, call the parsedParams(_ url: URL, fromTemplate: template: String) -> [String: RouteParams] function, key the split template string, take out the corresponding value in the url, and assemble it into the [String: RouteParams] dictionary to return. Finally, the returned dictionary flatmap(route), that is, the corresponding analytical function will be passed in, and finally the Navigation returns
public static func match(_ url: URL) -> Navigation? { return (nil) { accum, templateAndRoute in let (template, route) = templateAndRoute return accum ?? parsedParams(url: url, fromTemplate: template).flatMap(route)?.value } }
private func parsedParams(url: URL, fromTemplate template: String) -> RouteParams? { ... let templateComponents = template .components(separatedBy: "/") .filter { $0 != "" } let urlComponents = url .path .components(separatedBy: "/") .filter { $0 != "" && !$("?") } guard == else { return nil } var params: [String: String] = [:] for (templateComponent, urlComponent) in zip(templateComponents, urlComponents) { if (":") { // matched a token let paramName = String(()) params[paramName] = urlComponent } else if templateComponent != urlComponent { return nil } } URLComponents(url: url, resolvingAgainstBaseURL: false)? .queryItems? .forEach { item in params[] = } var object: [String: RouteParams] = [:] { key, value in object[key] = .string(value) } return .object(object) }
Through Navigation enum, a URL passed in deep link is parsed into a Navigation case, which makes the code highly readable and very clear.