Mac原生实现二维码分享文件

需求产生

使用Mac一年多,一直有一个小小的需求,怎样快捷的分享一个文件给Android手机呢?一开始我用的是HandShaker这款软件。

iShot2020-12-02 16.43.47.png

这个软件算是Mac上一款十分优秀的Android管理软件了。只要安装Mac端和手机端,同时打开软件,并保证在同一个局域网中,就能很方便的连接。连接成功后可以管理手机照片,音乐,视频,文件,同步剪切板,功能齐全,很棒!但是,我的需求是“快捷分享一个文件到Android机”,它显然不太符合“快捷”这个需求点,两个设备要经过安装>启动>连接这个基本流程才能将文件分享到手机。如果你是给别人分享,还得让别人安装APP,而且这APP也不算大众应用,很有可能在它的应用商店还搜不到,折腾来折腾去,想想就麻烦,弃之!ps:并不是它不好,是我眼光高😁。

直到后来,我又遇见了另外一个应用,极速分享

iShot2020-12-02 17.00.22.png

打开软件,拖入要分享的文件,点击分享,就会生成一个局域网链接和链接的二维码,手机用户的话直接扫描二维码打开一个网页,点击文件下载按钮就能把文件下载到手机了。

iShot2020-12-02 17.05.29.png

这个不需要Android机安装任何APP,只是简单的扫码下载就行。不错,终于算是实现了我的需求了。然而在我实际的使用中,慢慢的发现,它还是不够完美。它不能在访达中选中文件的时候直接从右键菜单中一键分享,只能先去打开应用,再回来拖文件,这便产生了体验的割裂感。而我要的是一种无感的分享流程,所以,很遗憾,亦弃之!

思来想去,既然第三方软件帮不了我(或者是我还没发现能实现我需求的软件),干脆我就自己搞吧!当然,不是说我自己写个Mac软件,因为我不会😂。我要利用Mac本身自带的东西,来实现我的需求,这个过程,要尽量的不依赖外来软件,只靠Mac本身。哦对了,上面提到的两款软件感兴趣的话直接可以在App Store中下载,都是免费的,感谢开发者🙏。

有了自己动手的念头,我大概花了三秒钟,考虑出了一个或许可行的方案。那就是模仿极速分享这款软件,这款软件的原理其实很简单,点击分享其实就是启动了一个服务器,然后将要分享的文件放到服务器资源目录中,再把文件对应的链接甩给用户就行了。如果用我作为程序员的角度来实现的话那很好说,什么Nginx,Tomcat的,随便搞一个配置一下就行了,但是这样的话对不了解这些的朋友而言显然有些不讲武德了,毕竟我们的目标是只靠Mac本身就实现我们的需求。

所需工具

自动操作

因此我又考虑了三秒钟,把计划完善了一下。首先我们介绍一下所要用到的工具。首先是Mac自带的“自动操作”应用,就是下面这货。

iShot2020-12-02 19.30.59.png

如果你不知道它是做什么的,那我简单介绍一下它,它就类似于iPhone上的“快捷指令”应用,如果你不知道快捷指令是做什么的,那我建议你百度一下,你如你已经被我的文章吸引住实在不想抽身去百度,那我就用我的理解给你解释一下,这个软件里面预置了很多自动化的操作,比如下面圈中的这些。

iShot2020-12-02 19.41.14.png

我们就拿选中的“拷贝访达项目”做一下说明,我们将其拖动到右边作为整个流程的一个步骤,从图中可以看到,当这个流程接收到一个文件的时候,经过第一个步骤“拷贝访达项目”时,它就会把这个文件拷贝到桌面上。然后我们还可以添加更多的步骤,做更多的操作,这个我就不一一举例了,后面我们的实践也会讲到这些具体的操作。看着这里,你可能会疑惑,那这个流程是怎么接收到一个文件的呢?是怎么执行的的?其实在我们打开自动操作的时候,选择新建文稿,这时我们发现会有以下几个类型让你选择。

iShot2020-12-02 19.51.29.png

我挑最常用的几个类型讲一下,选择“应用程序”,我们可以将之后创建流程生成一个Mac应用,如果你的流程是操作一个文件,那么只需将文件拖动到生成的应用上,它就会自动执行流程了。选择快速操作,它最终生成的是一个服务,这个服务就是我们今天的重点。

它是个什么玩意儿呢?你可以看一下当前打开应用的菜单栏,直接点击应用名>服务,就能看到它们。比如我现在选中的内容是一段文本,它就会出现文本对应的服务(百度一下),同时它也是一个URL,因此还有互联网对应的服务(打开URL)。

iShot2020-12-03 21.55.44.png

同样的,在访达里面如果你选中了一个文件,我们可以更方便的直接在文件的右键菜单里面看到文件对应的服务,比如下面这样:

iShot2020-12-02 20.24.48.png

所以说,所谓服务,就是针对你当前选中内容的一个功能菜单。怎样管理它呢?打开系统偏好设置,选择键盘>快捷键>服务,找到对应服务取消勾选就行了,鼠标右键点击服务,还可以直接在访达中显示,或者直接在自动操作中编辑这个服务。在这里,统一管理第三方应用自带的服务和自己开发的服务。

iShot2020-12-02 20.30.52.png

Apache服务器

扯得有点多了。我们继续介绍下一个所需的东西:一个服务器软件。这东西哪里找呢,前面说了可以用第三方,但是我偏不用。百度一番之后,发现原来Mac自带了一个Apache服务器。详见这篇文章

iShot2020-12-02 20.38.26.png

实现方案

讲到这里,我可以整体的说一下我的方案了。其实就是新建一个服务,这个服务的流程就是接收一个文件,将文件复制到服务器的资源目录,然后启动服务器,生成文件链接,最好是再生成一个二维码让用户扫,之后关闭服务器,再删除刚刚复制到资源目录中的文件,整个流程结束。之后我们只要在访达中任意选中一个文件,右键选择这个服务,就能执行以上流程,将这个文件分享出去,美滋滋。

所遇问题

然而无情的事实是这个方案虽然嘴上说起来很简单,但是实行起来却遇到了诸多的困难,甚至最终的解决方案也并没有做到十分的完美。

Apache服务器权限问题

首先便是这个所谓的系统自带的Apache服务器,我没用过,不是很了解。我按照上面博文中的方法启动了之后,往它默认的资源目录(/Library/WebServer/Documents)中放文件的时候发现需要输密码授权,因为这个服务器本身连同这个资源目录,都是属于系统的,只有root权限才能操作,我们普通用户操作的时候必须输密码。如果我在服务的流程中执行shell脚本,因为它是在后台运行的,根本没法输密码?就比如下面这句启动服务器的命令:

sudo apachectl start

正常情况下我们在终端里面输入之后点击回车,此时就需要手动输密码了,这对于我们的服务来说肯定是不现实的,就算我有能力让流程执行过程中弹出输入框让用户输密码,但这样会使整个流程的体验直线下降。所以几经百度,终于找到了解决办法。将上面的命令修改为下面这样就可以省去手动输密码的步骤:

echo '这里写上密码' | sudo -S apachectl start

具体的实现原理我就不解释了,感兴趣可以自行百度。

怎样将文件链接转为二维码并显示

紧接着又出现了问题,上面提到我启动了Apache服务器并将一个名为"test.png"的图片复制到了它的资源目录中。之后通过http://127.0.0.1/test.png成功访问到了这张图片。然而怎么将这个文件链接发给Android手机呢?用微信QQ?屁,如果用微信QQ了,那我直接把文件发给它不更好?搞这些有的没的,脑袋秀逗了啊?因此,最好的方案就是将这个链接转为二维码并显示在屏幕上。重复一下,这是两个步骤,一是要将链接转为二维码,二是要将二维码显示在屏幕上。那要怎么实现呢?我找遍自动操作里面的所有内置操作,遗憾的是并不能实现我的这两个看似简单的需求。除非借助第三方的力量,比如用Java将链接转为二维码,再用Java启动一个窗口展示这个二维码。然而对于普通用户来说,难道还要让人家装个jdk?配下环境变量?不讲武德,Shit!

最终,我找到了一个还算可以的解决方案。那就是借助第三方http接口。

iShot2020-12-02 23.26.51.png

我只要把我的文件链接以参数形式拼接到它的请求URL上,形成一个新的URL,之后用浏览器打开这个URL,就能直接显示我的文件链接对应的二维码了,妙!😎

文件链接不能自动触发下载

我试了下上述方法,很成功,用Android机扫描之后直接便打开了我分享的图片,那一瞬间我激动万分。然而很快我就发现不对劲。我是要下载文件到本地啊,它这直接把文件给我打开了,那怎么能行?这也让我产生了深深地疑惑:为什么极速分享生成的链接打开之后就是直接去下载文件,而我的是却是打开文件?都是普通的http链接啊,问题出在哪里?思考了一会儿,身为程序员的直觉告诉我,问题应该出现在这个链接返回的请求头上,于是我用postman调了一下极速分享的文件下载链接,在返回信息头部找到了这个:

iShot2020-12-02 21.21.44.png

我百度了这个Header代表的意思,说的都是一些晦涩难懂之词,翻译成人话就是,这个Header表示这个请求返回的是一个附件,是希望浏览器去下载,而不是打开,我的请求返回信息中没这个,所以浏览器直接就打开图片了。因此我需要让我的Apache服务器返回信息中包含这个Header。就这简单地需求,着实花费了我好长时间去百度去研究,好在最后算是解决了。方法就是修改服务器的配置文件:文件绝对路径是:/etc/apache2/httpd.conf,虽然我们可以在访达中找到这个这个文件并打开,但是修改后是不能保存的,因为没有root权限,所以我选择使用终端对这个文件进行修改,具体如下:

# 首先我们先临时获取root用户权限,回车后输入当前用户密码
sudo su
# 切换到配置文件目录
cd /etc/apache2
# 先备份配置文件当当前目录
cp httpd.conf httpd.conf.bak
# 之后开始修改配置文件
vim httpd.conf

如果是对命令行不了解的小伙伴,看图操作,下面便是执行vim httpd.conf命令之后的界面,其实它展示的就是该文件的内容:

iShot2020-12-02 21.37.48.png

我们按着方向下键,直到找到下面的内容:

iShot2020-12-02 21.42.33.png

此时点击键盘上的“i”键,进入输入模式,把圈中的部分修改成下面的内容:

<FilesMatch "\.*">
  Header set Content-Disposition "attachment"
</FilesMatch>

它的作用是保证当请求的内容是文件时,为返回信息添加一个名为Content-Disposition的Header,这样浏览器看到这个Header时,就会恍然大悟:“oh~~~返回的是个文件啊,那我就把它下载下来吧”。之后点击键盘上的“esc”键退出编辑模式,然后输入“:wq”,回车,这样配置文件就修改好了。这里插一嘴,“:wq”中的w指的是英文write(写),q是英文quit(退出),所以“:wq”就是退出vim并保存文件。如果只保存不退出,那就是“:w”,只退出不保存,自己琢磨。😉

需更改Apache服务器默认资源目录以保证系统安全

如果你已经尝试这么修改配置文件了,不如再改一些其它的内容。上面提到过,Apache服务器的默认资源目录路径是:/Library/WebServer/Documents,这个路径是系统路径,如果老是往里面塞东西删东西,万一对系统造成啥危害了这就不好了,所以我们可以修改一下这个默认路径,建议修改到当前登录用户的用户文件夹下。打开访达,在菜单栏中点击前往>前往文件夹,输入“/User”,找到你的用户文件夹(文件夹名是你电脑的用户名),点进去,新建一个文件夹,比如:Share,这里最好用英文命名。建好之后鼠标右键点击该文件夹,弹出右键菜单之后按住键盘上的“option”键,会发现原来的“拷贝”按钮变成了“将Share拷贝为路径名称”,点击它,这个文件夹的绝对路径就复制下来了,接下来我们继续编辑配置文件。找到下面的内容:

iShot2020-12-02 22.10.47.png

看到这里熟悉的路径“/Library/WebServer/Documents”了吗?把它俩都删掉改为刚刚拷贝的路径,然后退出保存。这样,Apache服务器默认的资源目录就更改为你刚刚新建的文件夹了,到时候我们只需要往这个文件夹中倒腾文件就行了。

至此,整个过程中唯一需要考验动手能力的步骤已经结束了,下面的则都可以直接使用我现成的劳动成果了。我呢,则是将这个成果的内容介绍一遍。

流程讲解

接下来,让我介绍一下这个至关重要的服务中的流程是怎样具体实现的。首先打开自动操作,选择新建文稿,类型选:快速操作,开始编辑流程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yFtBkbzX-1608003220940)(https://i.loli.net/2020/12/06/6kCHDYaI9GVb23R.png)]

注:shell脚本中,$*$@表示的是从上一步接收的全部参数,$#表示的是参数个数

①这里我们选择文件或文件夹,因为我们分享的无论是图片,音乐统统属这个范畴。

②这里我们选访达就好,一般都是在访达中选中文件进行分享的。

③这个步骤就是运行shell脚本,将要分享的文件放入Apache服务器资源目录并启动Apache服务器,然而具体步骤并没有这么简单,因为如果只选择了一个文件那就很简单,直接将文件复制过去就好,但如果用户选择的是文件夹或者是多个文件,又或者是有文件又有文件夹,那怎么搞?我给出的方案是把它们打包,然后让用户下载这个压缩包,于是乎,脚本如下:

# 判断是否只选中了一个文件(夹)并且它是一个文件而非文件夹
if [ $# = 1 ] && [ -f $* ];
then
	# 如果选中的仅仅是一个文件,则将该文件复制到Apache服务器资源目录中
	cp $* ~/Share
	# 返回选中文件的文件名
	echo ${*##*/}
else
	# 走到这里说明选中的是多个文件(夹)或者是一个文件夹,需将它们打包到Apache服务器资源目录中
	# 遍历选中的文件(夹)
	for i in $*
	do
		# 获取文件(夹)名称
		fileName=${i##*/}
		# 获取文件(夹)所在目录
		folderName=${i%/*}
		# 切换到其所在目录
		cd $folderName
		# 将该文件(夹)打包到指定的zip文件中(整个循环过程其实是将各个文件(夹)追加到了这个zip包中)
		zip -qr ~/Share/files.zip $fileName
	done
	# 返回打包好的zip文件的文件名
	echo files.zip
fi

# 启动Apache服务器
echo '这里写上密码' | sudo -S apachectl start

④将文件名赋值给变量“fileName”以备后用。

⑤经过上面的步骤,文件或者是打包的压缩包已经拷贝到了服务器资源目录了,并且服务器也已经启动,这里我们就需要拼接出这个文件或是压缩包的访问链接。拼接方法是“http://”+“Mac在局域网中的IP地址”+“/”+“文件名”,效果类似这样:http://192.168.50.9/test.png。不废话,上脚本:

#获取本机在局域网中的IP,拼接文件名,生成文件URL
fileURL=http://$(ifconfig | grep "broadcast" |awk '{print $2}')/$@
echo $fileURL

⑥这步接收上一步返回的文件链接,直接拷贝到剪切板中,方便分享。

⑦将文件链接进行URLEncode处理并作为参数拼接到二维码接口上面,之后返回拼接好的二维码地址

function run(input, parameters) {
	input = "https://wenhairu.com/static/api/qr/?size=350&text=" + encodeURI(input);
	return input;
}

⑧显示一条通知,提示用户分享成功。还要提示用户在下一步的网页弹出式菜单中点击“好”才会停止分享,点“取消”的话流程就此结束,需要自己使用命令行关闭Apache服务器并删除资源目录中的文件。

⑨用网站弹出式菜单加载二维码地址,展示二维码。因为我用的二维码接口返回的二维码是固定尺寸的,所以我设置了这个弹出式菜单的大小以获得更好的展示效果,如果后期更换了二维码接口无法保证返回的二维码的尺寸,这里弹出式菜单的大小尽量设置的大一点以保证二维码能展示全。

⑩获取文件名。

⑪这是最终步骤了,停止Apache服务器,删除复制到Apache资源目录中的文件。

# 关闭Apache服务器
echo '这里写上密码' | sudo -S apachectl stop
# 删除Apache服务器资源目录中的文件
rm -rf ~/Share/$@

效果展示

分享文件

2020-12-06 14.28.15.gif

接收文件

Screenrecord-2020-12-06-14-32-43-415.2020-12-06 14_48_35.gif

安装使用

  1. 首先在用户目录下面新建一个名为Share的目录

    mkdir ~/Share
    
  2. 开始修改Apache服务器配置文件

    # 我们先临时获取root用户权限,回车后输入当前用户密码
    sudo su
    # 切换到配置文件目录
    cd /etc/apache2
    # 备份配置文件到当前目录
    cp httpd.conf httpd.conf.bak
    # 开始修改配置文件
    vim httpd.conf
    # 之后照着上文中的操作修改配置文件
    
  3. 去我的码云把服务文件:文件分享.workflow下载下来,做一点小修改。修改的时候右键这个文件,选择“自动操作.app”打开,切记是“自动操作.app”,不是“自动操作安装器.app”,后者是要把服务安装到系统中时用的。

    iShot2020-12-04 18.43.21.png

    打开之后按照下图所示,将这两处的密码改成自己电脑的密码,然后command+s保存即可。

    iShot2020-12-06 18.48.48.png
  4. 保存之后再右击服务文件,选择“自动操作安装器.app”,此时服务就会被安装到系统中。理论上到此也就大功告成了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值