用IOS的捷径打造公交到站查询神器

需求引入

相信很多上班族每天都要坐公交,我也是其中之一。公交不如地铁等交通工具,需要等待的时间往往不那么固定,有长有短。对于上班这个场景来说,我们坐公交的时间往往是固定的,所以如果能知道公交还有多久到站,等快到站了再去公交站,那么等待的时间就会大幅缩短,这样大夏天的时候也不至于去公交站晒太阳。

为了解决这个问题,自然会想到在手机上通过一些实时公交查询平台查询还有多久到站。是的,相信大多数一二线城市都会有相应的查询平台,也可通过公交站是否有到站时间提示来判断,一般公交站有到站提示,那么基本上也就可以在手机上查询到。以我所在的城市上海为例,就有一个上海公交的公众号,可以通过公众号菜单的链接进入网页查询,输入线路名,选择方向,再选择站点,即可知道最近一辆还有多久到。这样每天早上又可以在家多呆一会了,懒癌患者就是我😎

这样真的方便了许多,但是用了一段时间后,发现每天查询的过程实在是太繁琐了,每天都要先打开微信,搜索公众号,点击菜单打开网页,输入线路,选择方向,选择站点。如果要再快一点,那最多也就只能将网页收藏,省去了查询公众号。那这时就有人会说既然可以收藏网页,那你把查询结果那个页面收藏不就可以了。是的,没错,我也想到了,可惜的是,那个网页是webapp类型的,不是传统类型,所以收藏查询结果是无效的。那么还有什么办法可以更快的让我们查询到公交的到站时间呢?这就是本文接下来要解决的问题。

原型设计

既然查询平台是一个网页,那也就意味着我们可以通过抓包的方式,将网页的功能抽离出来,自己用另外的方式实现。比如自己可以制作一个一打开就出现查询结果的网页等等。但是本文不会采用这个方法,因为这个需求本身并没有很复杂,如果自己做个网页的话,还需要部署到一台服务器上,未免有些大材小用。iOS系统的捷径app正好可以满足这个需求,而且成本也非常低,只需一个捷径app就行,完全没有其他任何额外成本,使用起来也很方便,可以说是不二之选。

根据前文提出的问题,我们需要解决的就是要将这些繁琐的步骤,尽可能的减少,最完美的就是能将它精简到一步。网页中的操作主要分为三步:

  1. 输入线路进行搜索,然后选择线路
  2. 选择线路方向
  3. 选择站点

对网页的抓包结果的分析:

  1. 选择完线路点击搜索之后,网页会提交一个请求,这个请求会将我们选择的线路名称提交,然后服务端会给我们这次查询的线路生成一个随机的id,这个id绑定了我们查询的线路
  2. 网页会跳转到线路页面,线路页面上方可选择线路方向,下方为线路站点列表,点击任意一个站点,即会发起一个请求,分析请求,携带了三个参数,一个是上一步得到的id,一个是表示线路方向,还有一个就是站点的序号。根据对请求结果参数名的猜测,可以得到站点的距离(米),距当前站点的站点数(个),到达当前站点剩余时间(秒),车辆的车牌号

结合上面的分析,发现通过抓包得到的信息比这个网页本身所提供的信息有用得多,网页上只显示了站点距离(个)、到站剩余时间(分)、车牌号,唯独没有显示距离(米),个人认为距离有时候比时间有价值的多,因为时间很容易受堵车等其他因素的影响,但是距离就不会。但是反过来想,在网页上显示距离(米)的成本很低,为什么确没有显示?我能想到的唯一原因就是这个距离是直线距离,不是实际行驶距离,所以没有很强的可参考性,但是再仔细一想,现在的路径算法非常成熟,应该不至于计算不出这种固定线路的距离。扯远了,回到正题,我们要做的很简单,就是模拟上面的两个请求就可以了。

在对这个网页研究的时候发现了网页存在的一些问题:

  1. 网页的选择方向区域,点击之后居然不是根据点击的线路来执行,而是每次点击之后切换到另一个方向,虽然从用户的行为上来说,点击一般都是为了切换另一个方向,毕竟只有两个方向,如果不用切换也不会点击,但是从界面上来说,这个效果和界面设计应该是不一致的,至少我从界面上来看,会觉得是点哪个方向就切换到哪个方向,哪怕点击的就是当前显示的方向,如果是要像现在这种效果,那么应该由一个“切换方向”的按钮去承载。
  2. 不知道是开发者偷懒还是什么其他原因,第二个请求中的站点id参数,果真就是和界面上显示的一样,还带了一个点,如果是第一个站点,那么参数值就是“1.”,而不是1,有软件开发经验的都知道,id不会莫名其妙带上这么一个“.”,服务端必然会把“.”通过一些方法给去除,但是这就导致了维护上的一个问题,如果有新人接手了这个系统,那么新人必然会对这段去除“.”功能感到疑惑,如果前端在提交这个参数的时候,就去除了这个点,那自然是最好的,成本反而更低。当然,对于这样的系统来说,成本的多少可能并没有那么重要。

开发实战

说实话,我在制作这个查询公交的捷径之前,对捷径这个app的了解也仅限于知道它是一个工作流app,可以自己定义一系列的工作流,完成一些繁琐重复的事情,但是对于如何去自定义自己的工作流还是一脸懵逼。这次为了方便自己,所以花了点时间摸索了一下,观察学习了一些别人制作的捷径,才基本了解它的开发模式。捷径的前身是workflow,后来被苹果收购之后有个官方译名“捷径”,我还是觉得译成工作流更能反映它的能力。它是由一系列操作构成的,操作有输入输出,通过将一系列的操作串起来,就可以形成一个完整的工作流。不过编写这个的思维方式和实际计算机开发中编码的思维方式还是有点不一样,在这里操作的输入输出和上下文中紧跟的操作有强关联,换句话说就是操作的输出和紧跟后面的操作的输入是相连的,而不像计算机编码,前后两句并没有很强的关联性。

为了解决我们的问题,我们需要用到的核心操作就是“获取 URL 内容”,这个操作可以帮我们发起一个请求,而我们需要做的只是发起两个请求。

以108路金陵中路黄陂南路到高境路恒高路方向的人民广场站为例

第一个请求中有个参数是线路的名称,叫idnum,我们只需要将自己乘坐的线路名称填入即可,由于请求返回的内容是一个JSON对象,我们可以利用捷径中的词典,解析这个JSON对象,并从中读取出sid参数,存储到变量中,供下一个请求使用。(后来分析返回的sid发现,这个sid其实就是线路的md5信息摘要,不会发生变化,所以这一个请求可有可无,但是出于保险起见,可以保留,避免服务端改变加密方式,从而导致下一个请求失败)

第二个请求有三个参数,一个是上一个请求返回的sid,一个是表示方向的stoptype,还有一个就是站点序号stopid。返回的内容还是JSON,只不过不是对象,而是一个数组,这就有点尴尬,找了一圈也找到该怎么直接取数组的值,只知道可以取对象里面的数组值,但是直接读取数组的值就不太清楚了,所以我采取了一个构造法,通过文本拼接,构造出一个对象,将返回的数组放在这个对象中,然后再进行取值,成功!

最后在通过“显示提醒”操作,将词典中的内容获取,拼接出一个提示信息即可,达到了文章开头视频中的效果

验收交付

经过对网页的分析以及工作流的制作,我们解决了文章开头提出的问题,完美实现了一键查询公交站点到站信息的功能,并且对捷径的使用有了初步的认识,希望大家可以自己尝试摸索捷径,通过制作工作流解决一些自己生活中的繁琐重复的事情,提高自己的效率。文末的阅读原文链接中,我也放上了自己制作的公交查询捷径,打开之后可以添加到自己的捷径中,有在上海的小伙伴可以通过自行修改里面的line(线路)、stopid(站点序号)、direction(方向)制作符合自己需求的捷径。文中所制作的捷径阅读原文中分享的,都还不是完美的,还存在一个问题,就是在查询结果中没有车辆信息的时候,捷径会返回一个错误信息,有时候是请求失败,但是更多的时候是因为站点还未发车,所以无法获取到车辆信息导致报错,有兴趣的读者可以自行修改解决。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注