欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

ios中Deep Linking实例分析用法

程序员文章站 2023-12-19 16:30:46
在 ios 中,deep linking 实际上包括 url scheme、universal link、notification 或者 3d touch 等 url 跳转...

在 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用法的详解内容,感谢你对的支持。

上一篇:

下一篇: