iOS 程序员效率提升利器之 AppleScript

这篇文章和大家分享我平时工作时,用来提升效率的神器之一:AppleScript。

AppleScript 虽然是一种脚本语言,但在我看来是最接近自然语言和最不具备计算机特质的编程语言了。即使没有计算机基础,在阅读基础文档和几个样例脚本之后,马上就能动手写出实用的脚本工具。

我感觉很多使用 Mac 系统的同学可能都没意识到,与自己每天作伴的 Mac 系统上还有这么一个强大高效的脚本语言,可以从各个方面提升自己的工作效率。接下来的文章和大家分享我使用 AppleScript 的两个场景。

在开始之前,先简单概括下 AppleScript 的应用环境。我们的 Mac 系统从应用的角度来看,其实就是一堆 App 的集合,系统自带的 App(Mail,Safari,Terminal 等)和安装的第三方 App(Firefox,Chrome,Outlook,iTerm 等),这些主流的 App 其实都向系统暴露了一些实用接口,用来将一些高频操作自动化。谁来调用这些接口呢?AppleScript。AppleScript 可以将这些 App 和 App 内部的数据,都当作对象来访问,甚至可以将不同 App 串联,自动化之后形成一个 workflow。

如何编写 AppleScript 呢?Mac 自带脚本编辑和运行工具,通过 Spotlight Search 搜索 Script Editor 即可。运行 Script Editor 之后,通过菜单 File -> Open Dictionary 即可打开如下图所示一个文档,里面列出来所有支持 AppleScript 的 App,以及各个 App 所支持的接口调用。

applescript00.png

提升工作效率,避免重复劳动

我最近在研究如何降低 App 的 Crash 率,每天都要实时监控是否有新的 crash 发生。所有可能严重的 crash 警报都通过邮件发送到我邮箱,一旦收到警报我需要将邮件中的 crash id 复制出来,去另一个网页工具里查询。每天早上看着一大堆警报,如果要将所有的 crash id 手动复制出来,一个个贴入网页里查询,操作很繁琐。AppleScript 可以轻松将这个流程自动化,一键搞定。步骤如下:

邮件分类

邮件都是保存在 Microsoft Outlook 中,我首先设置一个 rule,将所有邮件标题包含 Trending Crash:xxx 字样的邮件都存入一个子文件夹:iOS-Crash。

遍历邮件

再通过 AppleScript 遍历 iOS-Crash 目录下所有文件:

tell application "Microsoft Outlook"
    set theMessages to messages of folder "iOS-Crash" of default account
    repeat with theMessage in theMessages
    end repeat
end tell

上面这段脚本读起来是不是一目了然?就像是在和 siri 聊天一样,告诉 siri 遍历某个目录下的全部邮件。

提取 Crash ID

AppleScript 的另一个强大之处是可以和系统自带的各类常用命令行工具(比如 grep,sed,awk 等)交互,这意味着对文本和文件的操作可以游刃有余。接下来我要通过 sed 工具来提取邮件中的 Crash ID:

tell application "Microsoft Outlook"
    set theMessages to messages of folder "iOS-Crash" of default account
    set crash_id_set to {}
    repeat with theMessage in theMessages
        set msgContent to plain text content of theMessage
        tell me to set crash_id to do shell script "echo " & quoted form of msgContent & " | sed -E -n 's_.* crash_id:(.+)}_\\1_1p'"
        if crash_id is not in crash_id_set and the length of crash_id > 0 then
            set crash_id_set to crash_id_set & crash_id
        end if
    end repeat
end tell

关键代码是这一行:

tell me to set crash_id to do shell script "echo " & quoted form of msgContent & " | sed -E -n 's_.* crash_id:(.+)}_\\1_1p'"

AppleScript 用 tell xxx 的方式来切换脚步运行环境,比如

tell application "Microsoft Outlook"

是切换到 Outlook 的进程中。

tell me to 

是切换到当前用户的运行环境,因为我们要执行命令行脚步,需要更高级权限,所以要切换到当前用户进程。

接下来通过 echo 将邮件的内容传递给 sed,并提取出 crash-id,将值传回 AppleScript 中的便利 crash_id,放入数组中。

拼装 url 并在浏览器中打开

这是最后一步,将上面提取结果在浏览器中打开:

tell application "Microsoft Outlook"
    set theMessages to messages of folder "iOS-Crash" of default account
    set crash_id_set to {}
    set param to ""
    repeat with theMessage in theMessages
        set msgContent to plain text content of theMessage
        tell me to set crash_id to do shell script "echo " & quoted form of msgContent & " | sed -E -n 's_.* crash_id:(.+)}_\\1_1p'"
        if crash_id is not in crash_id_set and the length of crash_id > 0 then
            set crash_id_set to crash_id_set & crash_id
        end if
    end repeat
    
    repeat with crash_id in crash_id_set
        set param to param & "%22" & crash_id
    end repeat
    
    tell me to do shell script "cat ~/Documents/AppleScripts/ios_crash_url | sed -n -E s_crash_ids_" & quoted form of param & "_p | xargs open "
end tell

url 原始信息保存在文件 ios_crash_url 中,使用 sed 做简单替换之后,将 url 传递个 open 命令即可。

最后添加个命令 alias,就可以做到一键完成了。

alias ioscrash='osascript /Users/fenggao/Documents/AppleScripts/outlook_ios_crash.scpt'

代码重构

我还使用过 AppleScript 来重构 Objective C 代码,原理很简单,将 Xcode 中选中的代码以 text 的形式传递给 AppleScript,再通过 AppleScript 传递给命令行来操作。或者将 Xcode 当前打开的类文件 path 通过 AppleScript 传递给命令行工具,接下来就是基础的文件操作了,各类工具任由你选,比如我们可以使用本地编译好的 clang 来分析类文件,来进行针对 Objective C 语法特征的文本修改。当我们有大量的代码文件需要修改,而且修改的规则遵循某个相同的 pattern 时,使用脚本能起到事半功倍的效果。

通过 osascript 命令执行 AppleScript 是方式之一,另一种方式是通过 Service。每个 App 在菜单里都有 Services 一项。我们可以通过 Automator 来添加每个 App 都能使用的 Service。

我们可以把一个 Service 想象成一个 workflow,而一个 workflow 可以包含若干个 action,执行 AppleScript 就可以是其中的一个 action。

首先通过 Spotlight Search 启动 Automator,启动之后选择创建 Service。之后可以看到所以支持的 action,选择 Run AppleScript 并拖动到右侧的 workflow 区域,即可执行某个 AppleScript 了。当然也可以拖动 Run Shell Script 到 workflow 区域,各个 action 之间可以通过 stdin 传递数据。如下图所示:

applescript01.png

所有创建保存之后的 service 都会自动保存到 ~/Library/Services/ 目录下,一旦保存我们就可以在应用的 services 目录下看到我们的目标,比如我保存 xcode-text.workflow 之后。我在 Xcode 中选择某些代码,右键就可以看到我所创建的 service 了,如图:

applescript02.png

关键字:automator->service->action->applescript

总结

AppleScript 的应用场景很广泛,且很容易上手。一些 Mac App 的核心功能甚至都是利用 AppleScript 来编写的。比如 Mac 上的剪贴板工具,就是通过 AppleScript 来操作其他应用的当前编辑文本,来实现历史查找和插入功能。工具的强大与否在于使用之人如何用之,工具都是越用越称手。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,471评论 25 707
  • 用到的组件 1、通过CocoaPods安装 2、第三方类库安装 3、第三方服务 友盟社会化分享组件 友盟用户反馈 ...
    SunnyLeong阅读 14,463评论 1 179
  • 今天上课学习了时间管理来安排事情,我觉得这是个非常需要好好思考学习的。因为我就觉得自己是个有拖延症的家伙,而且有时...
    FineYoga陈泋文阅读 156评论 0 1
  • 读经时间: 2017年4月23日 星期日 晴 读经人员: 妈妈 读经内容: 《易经》系辞上传 第五章-第六章;...
    161d968e601f阅读 164评论 0 0
  • 前几天看到有人说医保不够用,上面给医院指标,医院超出额度就不给开了。感觉最近两年药房里很多便宜点的药没货了,能开的...
    花椒树阅读 232评论 0 0