airshare with swift
/ 7 min read
前言
由于苹果的玄学,我的handoff功能失效了。而我经常有这样的需求:手机打开电脑的当前网页。
Handoff功能失效前的操作步骤是:复制链接(chrome),手机上打开Safari打开链接。失效后我只能通过第三方软件发送链接到手机,复制链接,再粘贴链接到Safari。
幸好发现了这个软件,让我节省不少工作时间,但是算下来并没节省多少,这需要让我打开这个软件,点击软件上的按钮才能用airdrop。
于是就开发了自己的commandline。
食用方法
Step0 项目过程
编写的Swift程序可以无缝调用AppleScript,通过AppleScript可以获取chrome/safari浏览器当前页面链接,再将链接返回给程序,继续调用苹果的ShareService,可以分享到推特/微博/mail/airdrop。
Step1 初始化项目
注意这里新建的项目是CommandLineTool。
CommandLineTool入口文件是main.swift
,传统macOS/iOS项目都会用@NSApplicationMain/@UIApplicationMain
来简化入口文件,CLT会顺序执行main.swift
中代码,如果不手动添加application,程序将会在main最后一行执行完毕后退出,那么我们如何执行异步操作呢?比如项目里异步调用ShareService
服务?下文再述。
Step2 格式化输出
cmd虽然没有UI花哨的界面,但单调的输出也是比较乏味的。多亏喵神的RainBow,可以对console加点颜色。
这里将程序的标准输出进行了分类:
- 标准输出
- 错误输出
错误输出红色粗体。
其他输出默认颜色。
printUsage
函数是CLI的食用方法打印。
Step3 关键代码
getUrl
方法通过执行AppleScript来获取浏览器当前页面链接,具体的script如下:
share
方法将传入的url通过调用系统Service分享到airdrop。
Step4 解决异步
step1提到了如何异步操作时候,程序不退出。有两种方法。
- 使用while循环,获取用户输入
FileHandle.standardInput
- 手动添加NSApplication
本程序采用的是第二种方法,因为使用第一种方法会报fault] 0 is not a valid connection ID.
这个莫名的错误,导致不能成功调出airdrop。
这里会生成一个app在后台跑着。
传统的iOS/macOS,只要run程序,就会调出来一个模拟器/有无窗体的window,如何禁止调出来而在后台跑呢?
可以在.plist中添加一个:
mattt大神的terminal-share就是这样做的。
Step5 调试与发布
点击了run,其实就是执行了./path/program
这样一个命令,可以通过图一图二添加其他运行参数,这样就是执行了./path/program -c
。
也可以在finder中找到程序本身,cd到目录下运行之。
确保程序完备后,可以添加此CLI到系统:
这样在任何目录下都可以识别AirShare
这个命令了。
Step6 @TODO
每次执行程序都会遇到这样的警告,这貌似是系统的bug,网上也没有解决方法,并且每次使用此命令调用系统的airdrop,airdrop窗口总是会在所有窗口最下面。应该是这个系统bug造成的。
将错误输出到错误日志:
参考
- Swift Command Line Tutorial
- Mattt大神的terminal-share
- 开源的WebDrop
- ApplicationMain
- ApplicationMain2
- Application is agent
- ApplicationMain3