ios中Deep Linking实例分析用法
在 ios 中,deep linking 实际上包括 url scheme、universal link、notification 或者 3d touch 等 url 跳转方式。应用场景比如常见的通知,社交分享,支付,或者在 webview 中点击特定链接在 app 中打开并跳转到对应的原生页面。
用的最多也是最常用的是通过 custom url scheme 来实现 deep linking。在 application:openurl:sourceapplication:annotation 或者 ios9 之后引入的 application:openurl:options 中,通过对 url 进行处理来执行相应的业务逻辑。一般地简单地通过字符串比较就可以了。但如果 url 跳转的对应场景比较多,开发维护起来就不那么简单了。对此的最佳实践是引入 router 来统一可能存在的所有入口。
这里介绍的一种使用 router 来组织入口的方法是来自与 kickstarter-ios 这个开源项目,是纯 swift 开发的,而且在 talk.objc.io 上有开发者的视频分享。
在工程,通过定于 navigation enum,把所有支持通过 url 跳转的 entry point 都定义成一个 case。
public enum navigation { case checkout(int, navigation.checkout) case messages(messagethreadid: int) case tab(tab) ... }
在 allroutes 字典中列出了所有的 url 模板,以及与之对应的解析函数。
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, ... ]
在 match(_ url: url) -> navigation 函数中通过遍历 allroutes,去匹配传入的 url。具体过程是:在 match 函数内,调用 parsedparams(_ url: url, fromtemplate: template: string) -> [string: routeparams] 函数,将分割后 template 字符串作 key,取出 url 中的对应的 value,并组装成 [string: routeparams] 字典返回。最后将返回的字典 flatmap(route),即传入对应的解析函数,最终得到 navigation 返回
public static func match(_ url: url) -> navigation? { return allroutes.reduce(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 != "" && !$0.hasprefix("?") } guard templatecomponents.count == urlcomponents.count else { return nil } var params: [string: string] = [:] for (templatecomponent, urlcomponent) in zip(templatecomponents, urlcomponents) { if templatecomponent.hasprefix(":") { // matched a token let paramname = string(templatecomponent.characters.dropfirst()) params[paramname] = urlcomponent } else if templatecomponent != urlcomponent { return nil } } urlcomponents(url: url, resolvingagainstbaseurl: false)? .queryitems? .foreach { item in params[item.name] = item.value } var object: [string: routeparams] = [:] params.foreach { key, value in object[key] = .string(value) } return .object(object) }
通过 navigation enum,把一个 deep link 方式传入的 url,解析成一个 navigation 的 case,使得代码具有了很高的可读性,非常清晰明了。
以上就是小编整理的关于deep linking用法的详解内容,感谢你对的支持。