MW Logo

URI Scheme 的最佳实践



在Web时代,我们推崇使用Restful的架构,因为Restful能够更好地使用现有Web标准中的一些准则和约束。虽然Rest本身受Web技术的影响很深, 但是理论上Rest架构风格并不是绑定在HTTP之上,而且Rest跟资源与URI关系又非常密切。

那什么是资源呢?任何事物,只要有被引用到的必要,它就是一个资源。资源可以是实体(例如手机号码),也可以只是一个抽象概念(例如价值) 。下面是一些资源的例子:

  • 某用户的手机号码
  • 某用户的个人信息
  • 最多用户订购的GPRS套餐
  • 两个产品之间的依赖关系
  • 某用户可以办理的优惠套餐
  • 某手机号码的潜在价值

要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。URI既可以看成是资源的地址,也可以看成是资源的名称。

同样,在App里我们使用URI Scheme来像定位一个网页一样,定位一个应用甚至应用里的某个具体的功能。URI Scheme的通用格式是:
scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

一般情况下,我们推荐这样使用URI Scheme:
scheme://host/path?query

下面这张图展示的例子,显示了uri和它的各个组件。

那么URI Scheme是如何工作的呢?以大众点评的官方网站和大众点评App做个简单对比来进行说明。前者是网页的url,后者是App的URI Scheme。

网页 app
网站首页/打开应用 http://www.dianping.com/ dianping://
子页面/具体功能 http://www.dianping.com/shop/1859284/ dianping://shopinfo?id=1859284

在这里,http://www.dianping.com 和 dianping:// 都声明了这是谁的地盘。然后在http://www.dianping.com 后面加上 /shop/1859284/ 就跳转到从属于 http://www.dianping.com 的一个网页上;同样,在 dianping:// 后面加上 shopinfo?id=1859284 就进入了大众点评App的一个具体的页面——上海来福士广场。

因此,每一个App如果都规划好自己的URI Scheme,那么可以方便其他App快速唤醒它的某一个功能。

以格瓦拉为例,它的URI Scheme就规划得非常好,细粒度的控制。

  • 电影列表服务:能够进入格瓦拉App的电影列表页面
  • 电影详情服务:能够进入格瓦拉App某一部电影的详情页面。这个服务的URI Scheme类似于gewara://com.gewara.movie?movieid=123456
  • 电影院详情服务:能够进入格瓦拉App某一家电影院的页面。这个服务的URI Scheme类似于gewara://com.gewara.movie?cinemaid=123456
  • 影院场次服务:能够基于日期查看格瓦拉App中某一家影院电影的排期情况。这个服务的URI Scheme类似于gewara://com.gewara.movie?cinemaid=123456&date=2016-05-20
  • 影片视频服务:能够进入格瓦拉App查看某一部影片的片花。这个服务的URI Scheme类似于gewara://com.gewara.movie?videoNo=789000&movieid=123456

这些URI Scheme是格瓦拉比较有代表性的,有了这些Schemes可以方便其他的App快速唤醒格瓦拉App,同时也方便借助H5页面唤醒原生的格瓦拉App。既方便了引流,也便利了App的自增长。

我们魔窗sdk是做deep link的,它支持URI Scheme动态传值,只限于在path和query中传值。

1) path中可以动态传值的例子
myapp://myhost.com/:userId
userId表示是动态参数,它表示的服务可能是用户中心的服务

2) query中可以动态传值的例子
myapp://myhost.com?order=:orderId
orderId表示是动态参数,它表示的服务可能是查询某个订单的服务

myapp://myhost.com?cityId=:cityId&hotelBrand=:hotelBrand
cityId、hotelBrand表示是动态参数,它表示的服务可能是某个城市某个酒店品牌的列表服务

3) path、query中都可以动态传值的例子
myapp://myhost.com/:userId?order=:orderId
userId和orderId表示是动态参数,它表示的服务可能是查询某个用户的某个订单的服务