準備把本身開發獨立應用的文章整理成一個系列,本篇介紹下我最近剛上線的一個 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 和體驗問題了,已經發布了 六七個版本,相信不斷的優化,會帶來用戶的支持。另外後續也會有一些內容方面的計劃,對應用的推廣和粘度應該會有不錯的幫助,須要慢慢去實現。