最近接了一个内部工具开发的需求:运营人员需要生成商品尺码图片,之前他们是用PS做的,现在想让我们做个程序工具化这个过程。
刚拿到这个需求,分析之后,想了两个方案:
- APP生成图片,导出到电脑
- h5生成图片save到电脑
- 脚本生成,因为UI比较复杂,需要获取数据,所以排除
由于对APP开发比较熟悉,所以尝试着用客户端去做,生成图片不难,关键是如何导出到电脑上,当时的思路是
- iOS的话保存到相册用AirDrop去传
- Android保存到SD卡上,用PC上的软件导出
- 打成zip包,客户端起一个server,把zip download下来
本着操作简洁的原则,开始探索第三种方案。
一个程序,对用户来说只要有输入和输出就行了,中间不需要什么过多的介入,这才是优化流程的意义所在。
在这个例子中,输入是商品id数组,输出是一个zip包。
设计流程是:接收一个商品id数组,开始进行处理,最终输出一张图片save到Documents的一个文件夹下,然后进行zip打包,最后进行下载。
遇到的问题:
1.iOS的AutoLayout
,图片的模板是用AutoLayout
实现,变高(基于AutoLayout
中view
的ContentSize
概念)。问题就是截图的时候会报警告,然后出的图是空的,debug之后,发现是view赋值之后没有进行layout,所以size是CGSizeZero
的,截图时得到的context是0x0,之前在项目中,没有出现此问题,是因为view一般都会有superview,而superview在layout的时候subview也会layout。这里的view没有superview,所以没人触发它的layout过程,加了两行代码,完成。
1 2 |
|
2.在提交商品id数组之后,如果处理过程是异步的,那么如何通知用户是个问题,本来打算是手机local notification通知,但是我们这个APP直接部署在局域网的Mac Pro的模拟器里面,不需要用户安装,而web页面做push操作比较麻烦,所以采用同步处理,也就是说,提交过商品id数组之后页面一直loading,直到处理完毕,给出下一个页面。在APP端,商品信息的加载和商品主图的加载也是异步的,那么怎么才能在一个请求中做同步呢,也就是收到web请求的时候,提交到一个manager中去处理这部分商品,但是这里sleep掉,等那边处理完毕之后,再唤醒接着返回response,于是就想到了iOS的Runloop
这个机制。代码如下:
MyHTTPConnection.m
1 2 3 4 5 6 7 8 9 10 11 12 |
|
注解: 这块代码执行的环境是在HTTPServer的队列里面,所以在哪个线程中是未知的,线程中的runloop默认是不开启的,所以在这里,做了几件事
- 声明一个port放在runloop中,防止runloop中没有任何输入源会直接退出
- 把当前所在的thread赋给manager,当处理完成的时候,在这个thread上performSelector,唤醒runloop
- 在while循环中启动runloop
- 把之前的port remove掉
- 把runloop停掉
- 之前引用的thread清空
最终实现,3个操作步骤
localhost:8081/create?id,id,id,id
图片生成请求,response返回的时候处理结束,会在Documents/export/
的文件夹下生成以商品id命名的图片localhost:8081/zip
将Documents/export
打包成Documents/export.zip
并删除Documents/export
localhost:8081/export.zip
下载zip
其实可以把打包操作合并在第一步中。缩减为两步
思路来源是,QQ阅读传pdf的时候是在电脑上打开一个网页,然后把文件拖进去就可以同步到手机。实现之后发现,这个功能和Charles
的Web Interface
功能一样。。