前言
在 GitHub 上闲逛时,发现一个叫做 shortcuts-js
的项目,其描述写的是“A JavaScript iOS 12 快捷指令 creator”,花了几个小时的时间玩了一下,发现挺不错。
iOS 12 推出了一个叫快接指令的功能,能让你通过一连串的操作组合,自动化你的工作流。而这个项目的作者通过逆向“快接指令”上的程序,写出了一套 JavaScript 工具,让你能用熟悉的 JavaScript 来写 iOS 快捷指令。
想玩玩的话可以从 iPhone 上下载:https://www.icloud.com/shortcuts/efffb762336744a5857d5defe6ff0ba7
下载前记得要先到 “设置” -> “快捷指令” 开启 “允许不受信任的快捷指令” 开关。
下载之后到快捷指令中把 在共享工作表中显示 选项打开,这样才能在 safari 的网页分享中找到“快捷指令”来执行。
iOS 快捷指令
在 iOS 快捷指令出现之前,有一个名为 Workflow 的程序可以让你通过自定义的脚本实现自动化流程,而在 Apple 将其收购之后集成到了 iOS 12 中。
快捷指令的操作有点像 Scratch,可以把一个个的操作块任意组合,也能够串连别人做好的快捷指令,对于不会写程序的人来说,操作上算是很友好了。
在其中可以加入各种内建指令,拖拽组合成你想要的顺序。
操作的输出可以作为下一个操作的输入,也可以与 App 互动,例如可以串连到 Pocket:
除了上面这种简单的指令堆叠,也支持 if-else
结构:
但是没有几个程序猿能忍受在手机上面对一个个的动作进行拖拽组合,然后再输入内容,这实在是太麻烦了。
还是直接写程序比较舒服,而对于熟悉 JavaScript 的前端程序猿来说,shortcuts-js
简直就是一个神器。
shortcuts JS
shortcuts JS 基本上就是将 Apple 内建的操作都制作成对应的 JS 版本,你可以编排与屌用那些 JS 函数,shortcuts-js 会帮你转译成 iOS 能运行的 shortcuts
文件。
在 shortcuts JS 的网站上就有一个 playground 可以让你实际玩玩,并能下载成 shortcuts
文件,不过从 iOS 13 开始,不能够直接将 .shortcuts
文件用 AirDrop 复制到手机中,需要通过 icloud link 才行。
另外从官网和 github issue 得知,目前并不是所有 Apple 内建的操作都支援,所以要实现一些有创意的快捷指令还不是那么容易。
官网上的例子
//////// Import necessary actions and function ////////
const { actionOutput, buildShortcut } = require("@joshfarrant/shortcuts-js");
const {
comment,
wait,
runJavaScriptOnWebPage,
} = require("@joshfarrant/shortcuts-js/actions")
///////////////////////////////////////////////////////
//////// Create and arrange actions ////////
// We'll use this later to reference the output of a calculation
let calcVar = actionOutput();
// Define a list of actions
const actions = [
comment({
text: 'Hello, world!',
}),
number({
number: 42,
}),
calculate({
operand: 3,
operation: '/',
}, calcVar),
showResult({
// Use the Magic Variable
text: withVariables`Total is ${calcVar}!`,
}),
];
/////////////////////////////////////////////
//////// Generate the Shortcut data ////////
const shortcut = buildShortcut(actions);
// Write the Shortcut to a file in the current directory
fs.writeFile('example.shortcut', shortcut, (err) => {
if (err) {
console.error('Something went wrong :(', err);
return;
}
console.log('Shortcut created!');
});
//////////////////////////////////////////////
用 shortcuts js 制作一个基本的快捷指令非常简单,只需三步:
- 载入你想要使用的 操作。
- 创建一个
actions
数组,将你想要执行的操作按顺序放进去,基本上每个操作都会有 output,而每一个 output 都会自动传给数组中的下一个 操作。可以从官方文件 查阅目前所支持的操作的输入输出都是什么。不过并不是很全…
- 最后通过 shortcuts js 的
buildShortcut()
函数将你所编排的操作转化成合法的 iOS 快捷指令的格式并写入文件。
这时你就能将这个文件放入 icloud 上,并生成 icloud shortcuts link 下载到你的手机。
先来解释一下官方例子的操作都做了些什么:
const actions = [
comment({
text: 'Hello, world!',
}),
number({
number: 42,
}),
calculate({
operand: 3,
operation: '/',
}, calcVar),
showResult({
// Use the Magic Variable
text: withVariables`Total is ${calcVar}!`,
}),
];
shortcuts js 是用 TypeScript 编写的,所以你能清楚地看到自己载入的每个操作所需要的参数与类型。
comment
用来在快捷指令中加个注解,没有什么大用,你也只能在快捷指令的操作流中看得到它。number
让你能设定一个数字,将你设定的数字当作输出传给下一个 操作,在例子中是calculate
操作。calculate
除了接收上一个操作传入的输入外,你需要指定与输入操作的operand
与operation
;最后的一个参数是一个被称为 Magic Variable 的变量,用来储存操作所产生的结果,并能在其他操作中进行引用,例如例子中的showResult
。showResult
将你传入的text
参数值输出到手机屏幕上。在这里我们想要取得caculate
所输出的变量值,然而showResult
需要的是字串,所以不能单纯的传入变量,必须要使用一个特殊的函数withVariables
,将变量值读出并转成字符串格式。
在执行这个快捷指令后会在你的手机上跳出一个弹窗并显示 14 这个数字。
自己动手试试
下面是一个新闻核实的快捷指令,也就是说点击快捷指令后,可以输入想查询的新闻或事件,然后调用 Google 的 fact check api
,但是快捷指令虽然有提供 获取 URL 内容
的操作,却没有方便的数据处理操作,必须使用 dictionary
之类的操作将回传的 JSON 格式数据转存成 map 格式,操作上比较繁琐,可以参考一些大佬的经验:retrieving data
、parsing complex api responses
、scrapign web data
。
在花了一些时间用 shortcuts js 按照前面那些大佬的经验实验后,还是不成功,正当想放弃时,看到了一个名为 runJavaScriptOnWebPage()
的操作,可以让你在网页上插入 JavaScript 并运行。
看到这个后改变了一下思路,如果能在网页上运行的话更好,在网页上启用这个快捷指令,然后一切流程都直接用 JavaScript 在 web 页面上执行就行了,这样就不需要通过快捷指令的操作来处理数据了。
利用 runJavaScriptOnWebPage()
实现快捷指令主要代码如下:
const actions = [
runJavaScriptOnWebPage({
text: `
const element = document.querySelector('title');
const title = element.textContent;
const url = 'https://content-factchecktools.googleapis.com/v1alpha1/claims:search?key=GoogleAPIKey&query=' + title;
const result;
fetch(url)
.then(function(result) {
return result.json();
})
.then(function(data) {
result = data;
completion(result);
});
`,
}, output),
quickLook(),
];
剩下的就是把 response 再处理一下就可以了。
既然知道了可以在网页上运行 JavaScript,那就可以做更多事情了!
比如在github上的这位大佬 ,就利用这样的方式来 绕过 Youtube 视频在手机网页上无法背景播放的问题 ,这就是一个实用的快捷指令。
对于前面的例子而言,也是用相同方式,将 vConsole
inject 到页面中,代码非常简单:
// injectScript.js
module.exports = () => {
const script = document.createElement('script');
script.src = "https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
setTimeout(() => {
// hacky way to wait for script load
const script2 = document.createElement('script');
script2.text = 'window.vConsole = new VConsole();';
document.body.appendChild(script2);
}, 1000);
completion();
};
本来是想直接用 script.onload
在 vConsole
的脚本载入后进行初始化,但是不知道为什么无法顺利触发,所以只好用 setTimeout
的方式 hack 一下。(这种实现有时会导致需要启用两次快捷指令才能成功载入 vConsole …)
const injectScript = require("./injectScript");
// ...略
runJavaScriptOnWebPage(
{
text: `
const injectScript = ${injectScript.toString()};
const result = injectScript();
completion(result);`
},
output
),
// ...略
生成 iCloud link
前面说过从 iOS 13 开始,无法用 AirDrop 把 .shortcut
文件传到手机上,必须要通过 iCloud link 才行。
只要将你做好的 .shortcut
文件放入 iCloud Drive,通过 导入快捷指令 就可以从你的 iCloud Drive 中将文件下载下来并产生一个 iCloud link,接着 iPhone 就会自动检测到,也就能直接安装了。
最后再提醒一下,记得要到 “设置” -> “快捷指令” 开启 “允许不受信任的快捷指令” 开关,才能导入你自己的快捷指令。
总结
快捷指令这个功能非常有意思,通过快捷指令将常用的动作组织起来,一键就能完成,每个步骤省个三、四秒,整体可能就能省掉你十秒,如果这快捷指令很常用的话,势必能增加效率。
shortcuts js 还有很多地方可以改进,目前还缺少一些比较重要的操作,一些输入的参数目前也不是很好用,调试也不方便(必须要装上去才能测试)。