Life is a YOLO game

Sudo 開發日記 2016-05-06

May 08, 2016

工作內容

  • app 新功能大致開發完成,開始收斂修 bug,準備第一版送審

新發現的東西

1. Jenkins 2.0 on Docker

很多團隊都不敢貿然在開發流程中導入 Docker,一個很大的原因是許多 service 都還沒有針對 Docker 做過最佳化。2015 年 Docker 大流行時,網路上也出現不少質疑 Docker 將 service 虛擬化之後隨之而來的效能瓶頸。但持該論點的文章,大多都是採用短時間、高併發的 benchmarking (套一句行話來說就是「燒機」式的測試) 去測試 Docker 的性能,而不是真的讓 MySQL 跑在 production 環境上一段時間然後慢慢調整效能。但說實在地,未經測試的架構,誰又有這麼大顆的心臟敢放它在 production 環境上跑呢?

扯太遠了。這一週主要是發現 Jenkins 2.0 在 Docker 上執行的效能比 1.x 來說有非常顯著的改善。由於目前 Sudo 是使用 CircleCI 做 CI,還沒有做 CD,但在正式導入 CD 之前我預想到了一個問題。

CircleCI 的 IP 不固定,要怎麼樣在兼顧 AWS Security Group 政策的前提下執行 CD?

我目前想到最合理的替代方案是直接在 AWS 內建立自己的 CI/CD 環境 (至於怎麼架設還需要再研究,因為最終目的是一台 EC2 都不要管,全部改用 ECS),而 Jenkins 正是這一方面領域的佼佼者。但自行測試幾次 Jenkins 1.x 之後,不是安裝 plugins 時讓系統的 load 飆高到連 shell 都卡住的地步,不然就是正式建置專案時記憶體被塞爆 (在已經掛上 swap 的前提下)。曾經試著開 spot instance 去執行,但問題沒有解決。

連官方都在 Downloads 的選項中正式提供 Docker 的安裝方式,Jenkins 2.0 這次的表現讓我又對它抱持一線希望。

2. React Native 串接 Cocoapods 並透過 fastlane 部署時的陷阱

在茫茫 Google 中尋覓是否有人寫好 Flurry 或 Google Analytics 的 wrapper 一陣子之後,我放棄了。因為不是寫完之後就擺在那裡根本沒去更新 iOS library,不然就是一抓下來掛上去噴奇怪的錯誤 (Google Analytics 的 wrapper 在虛擬器中測試會噴 奇怪的錯誤)。絕望之下,我只好捲起袖子自己橋接 React Native 與 iOS library 了。

官方文件 寫得很詳細,而且我從 Exporting Swift (我很慚愧地表示我不會 Objective-C) 開始做,步驟少得有點過分。顫抖地按下編譯並執行,還真的可以跑 (數據有確實地傳回 Google Analytics,真心不騙)。

My code works but I don’t know why.

扯遠了。這一次真正要分享的是如果 React Native 有掛 Cocoapods,Fastfile 要一併更新,否則會發生找不到 library 的錯誤。例如以下這一行:

gym(scheme: "app", project: "ios/app.xcodeproj")

一開始開發 React Native 與設定 fastlane 時,它不會預設你未來會掛 Cocoapods 上去,因為不是每個人都會用到 Cocoapods,或可能使用了 Cocoapods 以外的套件管理工具。但如果第一次執行完 pod install,Cocoapods 其實會提醒你之後記得都要使用 *.xcworkspace 當作開發時的專案檔:

[!] From now on use `app.xcworkspace`.

我記得這件事,之後也都是使用 *.xcworkspace 開發,但每次透過 fastlane 部署的時候都會在 gym 那一步出錯,跟我抱怨說 ld 找不到 library 連結。明明開發時在虛擬機上面跑都沒有問題,為什麼部署的時候就會出錯?

這兩者唯一的差異不就是一個透過 Xcode 執行,一個透過 fastlane 執行嗎?

於是我打開 Fastfile,將那行該死的 gym 改成以下形式:

gym(scheme: "app", workspace: "ios/app.xcworkspace")

然後什麼都不必改,因為 Cocoapods 在建立 workspace 時已經把設定都寫進去了。部署成功。

於是,ld 找到它的歸屬,與 iOS library 從此過著幸福快樂的日子。

必須承認 React Native library 還是這麼少是非戰之罪,因為自己動手橋接真是太容易了,而且有很多 library 是依附在平台之上,要跨平台沒有這麼容易,根本讓人沒有動力去寫 for React Native 的 library。

3. React Native 動畫效果不要濫用

從 iOS 7 開始支援一種新的手勢,如果你從螢幕邊緣向右滑動,就可以回到上一個畫面。

Swipe gesture in Apple Mail

React Native 支援以下過場動畫效果,透過實作 NavigatorconfigureScene 來控制,目前支援以下幾種:

  • Navigator.SceneConfigs.PushFromRight (default)
  • Navigator.SceneConfigs.FloatFromRight
  • Navigator.SceneConfigs.FloatFromLeft
  • Navigator.SceneConfigs.FloatFromBottom
  • Navigator.SceneConfigs.FloatFromBottomAndroid
  • Navigator.SceneConfigs.FadeAndroid
  • Navigator.SceneConfigs.HorizontalSwipeJump
  • Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
  • Navigator.SceneConfigs.VerticalUpSwipeJump
  • Navigator.SceneConfigs.VerticalDownSwipeJump

其中最後名稱中包含 “Swipe” 字樣的四種效果使用上需特別謹慎,尤其是當你的畫面中有 carousel 的元件時,使用者的左右滑動會被 bubble up 到最上層的 View,然後被辨識為 iOS 的滑動返回手勢,這對使用者來說是預期之外的行為,應該避免。

目前的解決方案是在使用 carousel 元件的 View 上避免 Swipe 類的過場特效,改以 Float 或預設的 Push 取代。另外有一個潛在的解決方法是覆寫 carousel 的 onTouchStart 避免 event 被 bubble up,但由於還沒有認真研究過 React Native 的事件處理機制,所以就先不嘗試了。


Henry Wu
Written by Henry Wu who lives and works in Taipei producing some nasty bugs.
Author: Henry Wu License: MIT License: CC BY-NC-ND 4.0