准备把本身开发独立应用的文章整理成一个系列,本篇介绍下我最近刚上线的一个 app 《设计搞》的原理和开发中遇到的问题和心得等。api
第一篇笔记见:开发笔记(一):我的开发者的困境与突破缓存
app 下载地址:设计搞 on the App Storebash
主要是提供国外著名的设计网站 Dribbble 的图片和接口加速功能,Dribbble 虽然在国内没有被彻底封禁,可是访问特别慢,尤为是网站中的图片,加载速度惨不忍睹。app
由于我我的常常须要到 Dribbble 上寻找设计的灵感,特别是在移动设备上(iPad)需求很是强烈,因此一直以来,我都想作一个 client app,除了最基本的操做以外,最核心要提供 图片和接口加速。后来一想,这个事情好像很简单,因而说搞就搞,在网上找了一份开源的 client 代码,大改了一番,因而就成了“设计搞”这个名字颇有意思的 app。iphone
新版正在审核,logo 已经切换成了 banner 里的样子布局
应用自己涉及到客户端技术、服务端技术以及爬虫技术。优化
客户端网站
1. 核心是 GIF 浏览与保存。在列表页的时候加载 GIF 用的是 SDWebImage 内置的 GIF 支持,这些 GIF 都是简化过的,因此内存占用不高。可是在详情页里,不少 GIF 帧数很是高,画幅很大,SDWebImage 内置的 GIF 支持是默认把全部帧都解析到内存的,一张 GIF 可能会有 几百兆 的内存占用,有的甚至超过 900 M,直接会致使应用崩溃。后来改用 SDWebImageDownloader 将 GIF 下载,而后用 YLGIFImage 来显示 GIF,YLGIFImage 是一帧一帧解析图片的,内存占用不多。最最关键的是在视图销毁的时候手动回收一下图片的引用(在 dealloc 中将 imageView 设为 nil)。url
保存 GIF 是iOS 11 新增的功能,须要调用特殊的方法:spa
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSData *data = _shotData;
[library writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
if (!error) {
[SVProgressHUD showSuccessWithStatus:@"保存成功!"];
}else{
[SVProgressHUD showErrorWithStatus:@"系统错误"];
}
}];
复制代码
2. 其余都是普通的界面逻辑开发、推送集成、友盟集成、分享集成等,不过这里有一个问题,若是用原生的 UIActivityViewController 来实现分享的话,要注意在 iPad 上弹出分享视图时要兼容一下,不然会崩溃:
if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) {
activityVC.popoverPresentationController.sourceView = self.view;
}
复制代码
3. iOS 11 里的 safe area,若是你的应用有用伸缩布局之类的,要注意这个特性,iOS 11和 以前版本的 safe area 的定义不太同样,会致使一些界面的错位。解决方法也很粗暴,直接把 视图选项里的 safe area 取消勾选便可。
4. 另外,将你的 app 发布到 appstore 的时候,最近新增了一些政策,被我撞到的有:
服务端
1. 核心功能固然是如何用最底开发成本加入图片和接口访问。
咱们先讲图片,其实很简单,能够利用不少云存储的镜像功能来简单的镜像图片,所谓的镜像,就是当你访问云存储的一个路径的时候,若是云存储上找不到对应文件,就会去镜像的站点拉取对应的访问路径的图片,存储并返回给客户端。这里,咱们把 http://cdn.dribbble.com 做为镜像站点,我在取到全部图片以后,把 url 中的 http://cdn.dribbble.com 简单替换成云存储的域名便可。
例如把如下域名替换
https://cdn.dribbble.com/users/418188/screenshots/3824870/loading_animation_iphonex_tubik.gif
变成:
是同一个图片,而且路径彻底同样。
2. 预镜像图片
上面已经实现了镜像功能,这时候咱们把 app 里全部 http://cdn.dribbble.com 的图片访问域名替换掉便可完成加速。不过如今还有一个问题,第一次访问镜像图片的时候,由于须要去源站抓取原图,因此访问仍是会慢。因此须要作个脚本,替换用户第一次去访问全部图片。
这个其实也很简单,写一个脚本,定时去请求 dribbble 列表页的接口,取出里面全部的图片,而后 wget 一遍,这时候云存储就会把对应的图片缓存下来。固然还有一些细节问题,例如由于 dribbble 的源站访问很慢,因此一般须要有重试机制之类的。
3. 接口加速。
高潮来了,图片加速其实很简单,可是由于用了 dribbble 的开放平台接口,接口访问仍然很慢,并且最致命的是,dribbble 对每一个接口每分钟总的访问次数只有 60 次,崩溃啊,简直没法使用。必需要作接口加速+接口缓存了。
原理其实也很简单,在服务端用 Nodejs 作一个服务代理+强缓存。把客户端全部静态内容的请求,都转发到这个 Nodejs 服务,而后 Nodejs 服务把请求转发给 http://api.dribbble.com 把全部参数、header、路径 都转发给 dribbble。接收到结果以后,将内容按照path之类的特征缓存起来,下次接收到相同特征的请求直接返回缓存的内容,这样就能够达到接口加速的目的。
固然也有一些细节须要处理,例如缓存的特征究竟是什么?还有 header 的透传,还有返回的 header 也须要缓存之类的。
技术方面的东西差很少就这些了,但愿对你们有帮助。
关于推广,目前尚未正式推广过,就在知乎之类的平台发布过一些宣传,目前用户 3000 左右,还在不断增长中。感受做为一个我的开发者,作个 app 要作宣传仍是挺难的,毕竟没有钱不少渠道都上不了,不过我以为能够争取被 apple 推荐,虽然这很难,可是只要不断优化使用体验和内容,总有一天会被推荐,近期也一直在迭代这个 app,修复了 N 个 bug 和体验问题了,已经发布了 六七个版本,相信不断的优化,会带来用户的支持。另外后续也会有一些内容方面的计划,对应用的推广和粘度应该会有不错的帮助,须要慢慢去实现。