- 原文地址:Exploring Apps Without Jailbreaking
- 原文作者:
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:melon8
- 校對者:ALVINYEH
學習如何構建其他應用的五種簡單技巧
Medium 的 iOS應用是一個帶偽導航條的原生應用,而 Product Hunt 則是用 React Native 構建的。
Medium iOS 應用(左)和 Product Hunt iOS 應用(右)。
我是怎麼知道的呢?除了我自己編寫程式碼或向開發人員詢問以外,我可以用幾個簡單的測試來確定 —— 不需要越獄。
想知道我怎麼做的?
背景
在網路的“早期”時代,很容易瞭解任何網站是如何建立的。通過在瀏覽器中檢視原始碼,底層程式碼可以暴露給任何人看到、拿去混淆或者重用。隨著網路的發展和框架的使用,網站變的越來越複雜,到現在,這幾乎是不可能做到的。
使用 Chrome 檢查 Medium 文章的 HTML。
App 有相同的問題,但更糟。app 會經過編譯,這意味著原始碼已經從人類可閱讀的格式轉換為計算機友好格式。
雖然有工具可以反編譯 iOS 應用,但它們需要越獄裝置,特殊工具和專業程式設計知識。我將分享一些不需要任何黑客技巧的策略 —— 只要應用安裝在你的裝置上就夠了。
關鍵的理念
我們的策略很簡單:將應用推向極限,期待著出狀況。如果我們能看到它們出現的具體問題,就可以推斷它們如何工作。
我們將嘗試回答以下問題:
- 該應用是原生的嗎?如果不是,它是一個 web view?React Native?PhoneGap?Unity?某種 hybrid?
- 使用了哪些 UI 元素?是開箱即用的元件還是一些自定義的東西?如何使用它們來達到預期的效果?
實驗
為了收集資料,我們將做五個測試。我將解釋每項測試如何執行,尋找的目標是什麼以及從結果中可以得出什麼結論。
我們將測試:
- 按鈕觸控狀態 ?
- 互動式導航欄手勢 ?
- VoiceOver ? 4.動態型別?
- 飛航模式 ✈️
實驗 #1:按鈕觸控狀態 ?
一個按鈕看起來很簡單。你點選它,然後發生一些事情。但是,並非所有的按鈕都是相同的。
我們將測試按鈕互動的邊緣情況 —— 使用者不僅僅是點選一下按鈕時的行為。
iOS 開發新人常常對 UIButton
(iOS 上的預設按鈕元件)的互動複雜性感到驚訝。在互動中的不同節點有九個事件會發生。
touchDown
touchDownRepeat
touchDragInside
touchDragOutside
touchDragEnter
touchDragExit
touchUpInside
touchUpOutside
touchCancel
(在蘋果開發者文件中瞭解有關 UIControlEvents
的更多資訊。)
幾乎所有的按鈕都會在 touchUpInside
上執行一個動作(當使用者在控制元件邊界內觸控並鬆手時)。使用者觸控時,大多數按鈕都會表現出特殊的狀態。
真正的區別因素是按鈕如何處理 touchDragExit
和 touchDragEnter
事件。當使用者觸控按鈕時,按鈕如何響應,然後不抬起手指,拖動到按鈕之外,然後再拖回來。
在 iOS 模擬器中測試標準按鈕。
標準的 UIButton
有一些常見的行為:
- 拖回按鈕時的“觸控區域”大於按鈕的邊界。
- 在 touchDragEnter 和 touchDragExit 的時候有一個動畫。
但是,自定義的原生按鈕通常會丟掉這些預設動畫。
沒有動畫的自定義按鈕。
一個例子
我們來看看 Medium 應用。如果你在 Medium 的 iOS 應用中閱讀此內容,你可以直接在上面試試!
讓我們試一下右下角的這個看起來很花哨的按鈕:
如果你點選按鈕,然後按住不動,將手指向外移動並返回,你會發現手形圖示在其明暗狀態之間切換。
(我的下一篇文章:“我如何通過增長黑客來得到 10 萬使用者” ?)
React Native 按鈕
React Native 按鈕很容易認出來。它們通常有一個緩慢的淡入淡出動畫,並且適用於一切 React Native 按鈕。
Facebook 的 F8 應用中的按鈕動畫。這是 React Native 應用程式中的常見效果。
React Native 應用程式通常會大量使用滾動檢視,這會使按鈕的行為難以測試,因為拖動按鈕也會滾動檢視。
當談到 React Native 的話題時,另一個洩露祕密的表現就是 cell 的點選狀態。iOS 的原生 cell 點選後會出現一個純色背景,而 React Native 的 cell 點選後與其按鈕類似的高光效果。
左:React Native cell 行為。右:原生 cell 行為。
Web View 按鈕
在我下載測試的 PhoneGap 應用程式中,約 95% 的按鈕完全沒有觸控狀態,其餘的約 5% 保留了觸控按鈕的狀態,但在拖出或返回時沒有任何表現。
按鈕觸控狀態的結論
請記住很重要的一點,這些按鈕行為很容易被重寫。表現出特定的行為並不意味著一個絕對的原因 —— 它只是某個方向的線索。
但是隨著時間的推移,你會不自覺對按鈕有一種“感覺”,但它是探索 app 如何構建的,做出有根據猜測的最簡單方法之一。(這種技術也可以用來確定一個互動元素是一個按鈕還是其他型別的控制元件。)
實驗 #2:互動式導航手勢
從 iOS 7 開始,使用者可以通過滑動螢幕的左側邊緣來導航到前一個介面。這個手勢特別有趣,因為它是互動式的,這意味著它可以搓來搓去。
在 iOS 上使用標準的 UINavigationController
時,這種行為是自帶的。出於某種原因,許多應用程式棄用了標準導航欄,並最終導致了導航轉換效果的丟失,損壞或質量不高。
讓我們在 Medium 中試一下。
比較 Medium(左側)和 App Store(右側)上的導航轉換效果。
與標準導航轉換不同,Medium app 將導航欄與螢幕的其餘部分一起移動。而標準情況下,導航欄保持不變,上面的所有標籤會淡入淡出。
另外,Medium app 的前一個介面上的黑色半透明疊加層較暗,看起來導航轉換部分被重寫了,或者更有可能是直接使用了自定義的元件。
我個人認為它看起來非常好,並且理解他們出於設計和開發的需要而採取了這種方法。
React Native 導航
從開發的角度來看,React Native 中的導航功能實現起來更加困難。因此,React Native 應用程式傾向於使用自定義導航轉換,而不是使用UINavigationController
的標準“push”和“pop”。
Facebook 的 F8 應用程式中的自定義轉換效果。
iOS 上的預設模態演示不是互動式的,並且在重新出現的介面上沒有縮放效果。
以下是 React Native 中自定義轉換的另一個示例。
Facebook 的 F8 應用中的導航轉換效果。
沒有陰影或黑色疊加,但真正洩露祕密的表現是動畫時機。在這個 gif 中很難看到,但是在我抬手之後,動畫完成比平常慢得多。
就像按鈕觸控狀態一樣,通過測試許多導航轉換,你可以在一段時間的後獲得一種“感覺”。
互動式導航手勢的結論
這是我最喜歡的測試之一,因為它可以揭示更多關於 app 的資訊,而不僅僅是導航欄的工作方式。如果手勢把 app 搞出了 bug,則可能得到的資訊不僅僅是導航轉換的方式了。
但是,就像按鈕觸控狀態一樣,導航轉換可以被重寫。然而實際上,由於導航轉換需要大量的開發工作,所以導航轉換不太可能被嚴格定製。
實驗 #3:VoiceOver(旁白)?
你想要超能力?試試 VoiceOver。
VoiceOver 是 Apple 版本的螢幕閱讀器。適用於視力障礙使用者,這種輔助功能選項會大聲朗讀使用者介面。
VoiceOver 有另一個我們更感興趣的效果:它在當前選定的元素周圍顯示一個黑框。
在 App Store 和 Weather 應用程式中選擇元素的聲音。
這使我們能夠將介面分解成各個部分。不需要猜測介面是如何構建的,我們可以讓 VoiceOver 告訴我們!有時它甚至會大聲朗讀元素的型別(“按鈕”,“日期選擇器”等)。
如果您以前沒有使用過 VoiceOver,那麼它很值得去學習。基本概念:
- 在螢幕上拖動以選擇元素。
- 雙擊螢幕上的任意位置以“點選”所選元素。
- 左右滑動以在元素之間快速跳轉。
讓我們來研究一下在 Medium 中使用 VoiceOver 的效果。
使用 VoiceOver 在 Medium 中選擇帖子的標題。
大多數元素的表現和預期一致。VoiceOver 只是讀取選擇的內容或元素的名稱。但是,有一些不尋常的行為。
在主螢幕上,選擇帖子的標題只能讀取標題的一半。首先它說,“Color Contrast Crash C”,然後選擇標題的底部讀取“Course for Interface Design”。這說明 label 的佈局肯定有一些自定義的部分,這使得 VoiceOver 認為標題被分成多個 label,每行一個 label。(我的猜測是他們為自定義行間距的 label 構建了一個變通方案,而通常的解決方案是使用 attributedString
屬性,並且他們的方案可能會導致以後出現複雜問題。)
選擇描述 label 後,我們可以看到 VoiceOver 揭示隱藏資訊的威力。對於大多數使用者來說,label 只是顯示“估計有 2.85 億...”。但是VoiceOver告訴我們更多的資訊:“估計有 2.85 億人視力受損。這個數字包括從法律上來看這些人的人數“。在這種情況下說明,所有資料都儲存在標籤中,但視覺上被截斷了。
Medium 的 VoiceOver 演示。(確保你的聲音不是靜音)
如果幸運的話,你可以使用它來訪問你無法訪問的資訊。
這是另一個有趣實驗。在“書籤”選項卡上,如果你沒有書籤,則有一個不可見的標籤。它說:“要給文章加書籤,在任一地方點選書籤圖示,文章會被新增到這個列表。”
使用 VoiceOver 在 Medium 中選擇不可見標籤。
我猜是開發人員會快速暫時隱藏這個標籤,並假定可能將來產品又會讓它顯示。(或者,也許我正在被 A/B 測試。)
非原生應用程式
VoiceOver 也適用於基於網路檢視的 app。如果你聽到“連結”或“標題級別”等字眼時,表示你正在一個網路檢視之中。
此外,文字元素可能會基於樣式以各種奇怪的方式拆分(因為它的 HTML 表示),並且元素可能不會自然分組。
遊戲(由 Unity,SpriteKit 等構建)通常根本沒有任何 VoiceOver 支援。
VoiceOver 的結論
VoiceOver 提供的證據在這些測試中最可靠。它顯示元素的可視範圍,並可以讀取不可見的屬性。這是關於任何介面的寶貴資料。
隨著你更多地使用 VoiceOver,你會學習到各種 UI 元素的預設表達方式,並開始注意到它的不同之處。
與上述任何測試一樣,VoiceOver 不是 100% 可靠的。所有的 VoiceOver 文字和邊界框都可以由開發人員配置。針對 VoiceOver 優化過的應用程式也可能會揭露更少關於應用程式如何工作的資訊,因為開發人員會修復可能導致 app 出問題的 bug。
(專業提示:將 VoiceOver 設定為你的“輔助功能快捷鍵”,便於在測試時開啟和關閉。)
實驗 #4:動態型別?
與 VoiceOver 類似,動態型別 是適用於視力障礙使用者的輔助功能。它可以修改整個系統的文字大小。
我們想要使用動態型別來破壞佈局。有了新的“輔助功能中的更大字型”後,這比以往更容易看出 app 端倪,這絕對是巨大字型。
調至最大字型的“更大文字”設定介面。
動態型別 可以在設定 > 輔助功能 > 更大字型中設定。這也可以作為一個 widget 新增到 iOS 11 中的控制中心,以便於訪問。
不幸的是,Medium 不支援 動態型別,所以我們將使用 App Store 演示。
我將文字大小設定為最大值,並找到了一個錯誤的佈局 —— 搜尋介面上的一個廣告。
最大字型(左側)和預設字型(右側)的 App Store 搜尋介面。
文字“22K”佈局的非常好,但它沒有揭露太多佈局的祕密,因為佈局為更大字型做了調整(可以看到元素改位堆疊排列,而不是並排)。
我最喜歡的部分是淡藍色的“廣告”按鈕。和正常字型大小時的漂亮的圓角矩形不同,我們得到了一個怪怪的拉伸的形狀。
更大字型設定下的“廣告”按鈕。
我的猜測是,這個藍色框被繪製成一個硬編碼半徑的自定義路徑。通常,控制元件不會使用動態型別調整大小(請參閱“GET”按鈕作為示例),所以這裡有一些自定義內容。
####動態型別的結論
有些應用程式根本不支援 動態型別。即使支援,他們也可能不支援輔助設定中更大的字型。
但是當動態型別生效時,就可以對佈局進行壓力測試。使用 VoiceOver 已經可以瞭解一些資訊,結合動態型別更有助於驗證理論。通常支援動態型別的 app 也會測試這一部分,這會減少顯示有用資訊的機會。
實驗 #5:飛航模式✈️
另一個簡單的測試是啟用飛航模式。飛航模式會禁用 Wi-Fi 和蜂窩行動網路,這會立即導致網路請求失敗。通過在各種情況下禁用網路連線,我們可以看到 app 如何出問題。
在 Medium 中,如果你載入主頁,開啟飛航模式,並選擇一篇文章,文章仍會載入。事實上,整個帖子仍然可讀。
飛航模式下的 Medium。文字內容載入,但影象不載入。
由此,我們推斷 Medium 在載入預覽時會拉取整個帖子的內容(並進行一些快取)。
App Store 也會延遲載入影象。載入完一個頁面並滾動到底部之後開啟飛航模式會看到影象區域是空白的。
App Store 在飛航模式下。影象(即使在同一頁面上)似乎是懶載入。
大多數現代應用程式重度依賴於網路連線,來下載內容然後允許互動,所以飛航模式會讓大多數 app 出錯。
React Native 和非原生應用
在我測試過的 React Native app 中,大多數應用程式通過刪除螢幕上的所有內容,並顯示一條自定義的“無連線”訊息,對缺乏網際網路連線的情況立即做出反應。
對於基於 webview 的 app,大多數沒有反應。沒有跡象表明當前正在載入或者載入失敗。
飛航模式的結論
不幸的是,飛航模式並沒有給出如何構建應用程式的明確答案,因為大多數應用程式在沒有可用連線時會有某種回退方式。
想繼續深入?通過觀察 app 的網路流量,你可以瞭解更多關於其他應用的資訊。Charles Proxy(代理)的 iOS app 是洞悉各種 app 的好方法,但需要一些 HTTP 網路知識。
小貼士
儘管可能不能完全確定 app 的構建方式,但有一些方法可以讓你進行有根據的猜測。通過研究邊緣案例,我們可以更大程度上揭示它們的內部運作。
我們的學習也可以為我們自己的 app 的設計和開發提供資訊。多瞭解一些方法有助於我們在未來做出更好的決策。
在一個不開源的應用程式的世界中,做些小改動的能力有限。(或重新發現)思考事物運轉的方式的樂趣。
喜歡這個故事?在 Medium 上留言,並與 iOS 設計/開發者朋友分享。想要了解最新的移動應用設計/開發?在 Twitter上關注我:twitter.com/nathangitte…
感謝 David Okun 修改本文的草稿。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。