知识点:

  1. 操作:获取日期之间的时长(Get Time Between Dates)
  2. 捷径技巧:显示结果和显示提醒的区别
  3. 捷径技巧:递归

上一篇里,我们已经完成了一个可以开始计时的 Toggl 捷径。而且也已经把最复杂的步骤给处理完了。

接下来,作为一个比较高级的捷径,我们应该把要求再提高一点,使它更完整,也更加灵活。完整,是指不仅能够启动一个计时器,还能够停止它。灵活,是指这个捷径可以自动根据当前是否有计时器运行,来判断下一步的动作。具体来说,是要做到接下来这件 3 事:

  1. 捷径运行后判断是否有计时器正在运行
  2. 如果没有计时器运行则开始新的计时器
  3. 如果有计时器运行则询问是否停止正在运行的计时器
  4. 如果有计时器运行也可以询问是否停止当前计时器,并开启一个新的计时器

要做到这些也非常容易,实际上最关键和核心的步骤「捷径运行后判断是否有计时器正在运行」我们已经在《25–1 在捷径中完成 Toggl 认证》给实现了。

判断是否有计时器在运行

判断是否有计时器在运行需要的请求链接,就是在《25–1 在捷径中完成 Toggl 认证》提到过的:https://www.toggl.com/api/v8/time_entries/current

我们有了请求链接,也知道请求方法是「GET」,也知道如何认证,因此把这些步骤套在一起,就可以制作一个「获取当前 Toggl 计时器运行状态」的捷径:

认证部分的捷径操作(密码已修改)

首先不要忘了认证的部分。

在「文本操作里」填入 用户名:密码 或者 你的个人 Token:api_token,然后再将其进行「Base64 编码」。编码之后把它设一个变量。这整个认证的操作组合,最后都是为了这个变量,在我这里把它命名为了「auth」,随后它要被放在「获取 URL 内容」的相应位置,如图:

判断是否有计时器在运行的操作组合

我们先放一个「URL」,把发起请求用的 URL(https://www.toggl.com/api/v8/time_entries/current)放进去,再用「获取 URL 内容」决定请求方式和认证内容。

最后运行捷径会出现两个结果:

无计时器运行(左),有计时器运行(右)

有了这样结果的区别,我们就可以接上一个「如果」,如果接收到了左边的信息,也就是 {"data":null} ,就说明当前没有计时器运行。我们就可以把我们在《25–2 用 Toggl 的 API 在捷径中创建计时器》里制作的捷径放在这一步的下面。反之,如果是有一大堆数据,那么就说明当前有计时器运行。那我们就要询问是否停止当前计时器,或是否停止当前计时器再开启一个新的计时器。而这里是我们这一节要解决的问题。

停止当前计时器

Toggl 停止当前计时器的请求链接,是 https://www.toggl.com/api/v8/time_entries/当前计时器ID/stop。所以我们要完成这个链接,就要获取当前计时器的 ID。

好在这不是问题,在我们最初判断有无计时器运行的那个请求结果中,就有这个当前正在运行的计时器 ID:

查询正在运行的计时器 ID

所以我们在「否则」之后直接接「获取词典值」,先获取「data」,再获取「id」。随后把这个「id」作为魔法变量,放到下面「URL」里的请求链接的相应位置:

停止当前正在运行的计时器的操作组合

这里要注意的一点是,这个请求链接的请求方法变成了「PUT」。

到了这一步,如果你运行一下,其实就已经解决问题了。不过为了完善体验,我们还要让它再给我们一个提示,告诉我们上一个计时器是什么,运行了多长时间。所以这里我们要获取 3 个值:

  1. 上个计时器的描述
  2. 上个计时器的起始时间
  3. 上个计时器的停止时间

这 3 个值都能在返回的结果中获取:

查询我们需要的 3 个值

计时器的描述在「data」下的「description」里;起始时间在「data」下的「start」里;结束时间在「data」下的「stop」里。

虽然描述是现成的,但是运行了多久需要一个简单的时间计算,也就是计算时间差。这个时间差我们可以用捷径里的「获取日期之间的时长」来计算:

操作「获取日期之间的时长」

使用这个操作的特点有以下 3 个:

  1. 传入的数据要符合捷径中的日期格式
  2. 计算运行时间要由结束时间减去起始时间
  3. 它最后给出的结果是英文

根据这 3 个特点,我们需要分别进行一下应对。

首先我们应该先获取起始时间,因为这样可以让我们之后直接从结束时间的结果减去这个起始时间,可以少设变量,节省步骤:

获取计时器起始时间的操作组合

我们先从「data」里获取到开始时间「start」,然后加一个「文本替换」,把里面的「T」替换成什么也没有。为什么这么做呢?我们可以看一下前面 JSON 图中的细节,发现起始时间里的时间格式是019-01-20T06:46:11+00:00 ,它日期和时间之间有个「T」,这个「T」会影响捷径的识别,所以我们要用「替换文本」把它替换掉。

接下来,同理,我们继续从「data」里也获取结束时间「stop」,并把里面的「T」给替换掉:

获得计时器结束时间的操作组合

随后我们就可以加上「获取日期之间的时长」。

这个操作会直接把上一步传下来的结果当作结束时间,并根据这个来问我们起始时间。在「获取起始时间」里,有两个选项,「现在」表示当前时间,而「其它」表示你可以填写其它的时间。这里我们要用的就是「其它」,因为我们要填写之前我们设好的「起始时间」。最后我们要选择单位,这里只要选择「总时间」即可,它会将时间换算成「年月日时分秒」的形式,最直观:

获取日期之间时长的结果

最后,我们要在最后加上一个「显示结果」。这样就可以告知我们刚才停止的计时器是什么,总共运行了多久:

「显示结果」的结果

停止当前计时器并启动一个新的计时器

至此为止,这个捷径已经有运行,有停止,有报告,算是比较完善的一个捷径了。但是只要修改 2 个步骤,我们就能把这个捷径做得更灵活。

我们可以设想一下,我们肯定会遇到这样的使用情景——我正在运行 A 计时器,这时候我换了一件事去做,想直接停了 A 计时器,运行 B 计时器。目前我们这个捷径,得启动两次才能做到先停止,再运行。所以我们要做一个小小的修改,让它能够启动一次,就能够做到先停止,再运行。

要做到这一步,其实就是要在停止计时器之后,再重新返回到整个捷径的开始,把它再运行一遍。因为当我们停止计时器,再运行一遍捷径,这个捷径就会发现没有计时器运行,就会直接为我们启动一个新的计时器。那么有什么操作可以做到这一点呢?我们在《8 制作 App Store 捷径合集》里已经介绍过它——「运行捷径」:

操作「运行捷径」和它的位置

只要我们在最后的「显示结果」之后再加上一个「运行捷径」,并且这里是调用这个捷径本身,就能做到在停止计时器之后从头开始运行这个捷径。这种方法在编程里叫做「递归」,它可以很轻松地解决了我们停止计时器 A 后继续启动计时器 B 的问题。

但是,我们会发现,我们不是每次停止计时器后都想重新启动一个新的计时器。我们是有时候想,有时候不想。那么能不能在重启新的计时器之前让我们选一下呢?说到这,大家脑子里应该会蹦出不同的解决方法了,但是最简单的解决方法大家也许没想到,那就是用「显示提醒」去替换「显示结果」:

用「显示提醒」及效果

为什么呢?因为「显示提醒」会提供两个不同的按钮——「取消」和「好」。

当我们选择「取消」,这个捷径就不会继续运行。当我们选择「好」,这个捷径就会继续运行下去,就会触发「运行捷径」这个步骤,从头再运行一遍整个捷径。

把「显示结果」改为「显示提醒」,再在后面加一个「运行捷径」。就这么两个小修改,就让整个捷径变得更加灵活,可以应付一个新的需求。至此,整个「Toggl 计时器」捷径已经圆满完成。

捷径下载:Toggl 计时器

其它思路

在《Week 13:捷径和 API 相关的进阶技巧》一文中大家看到的,直接通过 Launch Center Pro 调用捷径,开始计时并跳转到应用那一套,其实基于「Toggl 计时器」这个捷径的小修改。主要修改了以下几个地方:

  1. 不再临时填写描述,而是直接在捷径里写定描述,减少交互。
  2. 不再临时选择项目,而是直接在捷径里写定项目,减少交互。
  3. 在运行「启动计时器」的部分后,加上 URL Schemes,使其可以自动跳转到应用。
  4. 在运行「停止计时器」的部分后,还可以通过 URL Schemes,使其可以自动退回主界面(这一步我没有做,方法见《专栏:x-callback-URL 的使用方法》)
  5. 在 Launch Center Pro 中通过 URL Schemes 调用捷径,方法见《索引:捷径的 URL Schemes 与使用建议

这里最重要的是前两步,它将「Toggl 计时器」这么一个比较泛的需求给凝聚到了一个目的上,从而让我们在启动相应计时器时是全自动的,不用人为干涉。

这也再一次说明捷径的灵活性,我们只要有需求,就可以根据自己的需求去修改已有的东西。「Toggl 计时器」以及我们讲过的没讲过的所有捷径,都不是铁板一块,钉死了就要那么做那么用。各位应该根据自己的需求发挥想象力,把它们修改成最符合自己想要的样子。

API 相关注意点小结

提交 API 请求 JSON 文件就像是我们去政府部门填表申请东西。只不过区别在于整个过程是机械化的,也就是说容错率极小,稍有差池机器(绝)不留情。因此我们必须得知道我们要填什么,然后还要严格按照规定的格式,一字不差,一个空格都不差地把这些内容填好,还要按照要求的方式提交上去。

尽管如此,根据我的经验,在捷径中使用 API 基本上搞定以下这几个步骤就不会出太大问题:

  1. 请求链接(1):先找请求链接,没有请求链接那整个捷径无从做起。
  2. 请求链接(2):一个请求链接只能做一个目的的事,一个捷径也许需要多个请求链接(最后 Toggl 计时器的总捷径用了 3 个以上的请求链接)。
  3. 请求方法:找完请求链接后找请求方法(Method),看是「GET」还是「POST」还是「PUT」……
  4. 认证方式:确定请求方法后找如何认证(如果需要认证)。
  5. 其它请求信息:在知道授权方法后,还要继续确定其它请求信息,要在文档里查看有没有什么必需(Required)的项。

接触了 API 之后你就会对文档的高低有判断了,好的 API 文档会让你查阅的时候跟看自己写的笔记一样,坏的文档真是缺张短页,查一个授权都能绕好几个页面。同时,查询 API 文档也是一个制作者耐心程度的比拼。因为它毕竟都是英文文档,谁能更耐心地阅读谁就能发现更多可用的细节和变化。那些耐不下性子读文档的人认为不能解决的事,往往被更能耐着性子读文档的人解决。前者可能会叫后者大神,实际上后者只是比前者踏实了那么一点,也许只是多看了细看了几行文档罢了。