2 個 SwiftUI 的除錯 (Debugging) 好工具 快速發現 App 的問題


本篇原文(標題:Two SwiftUI Debugging Helpers You Can Start Using Right Away)刊登於作者 Medium,由 Dheeru N 所著,並授權翻譯及轉載。

SwiftUI 內的 API 方法:Self._printChanges()

SwiftUI 提供了一個僅用於除錯 (debugging) 的好方法,讓我們區分是什麼改動讓視圖重新加載。這個方法是用來查找錯誤的。當我們看到視圖在重新調用 body 屬性 (property),卻又不知道原因的時候,這個方法就大派用場了。

struct PrintingChanges: View {
    @State var counter = 0
    
    var body: some View {
        Self._printChanges()
        return Button {
            counter += 1
        } label: {
            Text("Current Value \(counter)")
        }   
    }
}

以上的程式碼中有幾個重點:

  • 因為 _printChanges() 是一個靜態方法 (Static Method),我們需要使用 Self
  • 我們需要在 body 屬性內呼叫 Self._printChanges(),也就是說,我們需要在原本的視圖程式碼中,添加一個顯式 (explicit) return keyword。
  • 在預設情況下,所有視圖都有 _printChanges()
  • 所有從下橫線 (_) 開頭的函式和屬性都是 Private API 的一部分,因此我們不會看到任何相關文檔。

從以上例子可見,我們點擊按鈕後,如果在 Console 看到東西,就代表某個屬性發生了變化。也就是說,屬性的變化對 UI 有影響,所以 SwiftUI 在渲染 (render) 視圖。

swiftui-debugging-console-output

在我們開發 App 的時候,我們會使用不同的屬性包裝器 (property wrapper),那會導致視圖多次呈現。而如果我們使用 Self._printChanges(),就會印出多個視圖。雖然 Apple 說它們十分輕巧,但還是會降低 App 的效能。

重要事項

SwiftUI 只會在屬性有改變,需要重新評估 body 時渲染視圖。如果你在視圖中使用的狀態變數並不是用於 UI 的話,印出的結果就不會有視圖的改變,SwiftUI 也不會渲染那個屬性。

當我們利用 print() 印出 State 屬性時,SwiftUI 就會重新渲染視圖,因此我們可以使用 _printChanges() 而不是 print

記得要用 iOS 15 來構建你的 App,才可以用這個 API。

使用 Colored Background

當我們在螢幕上處理各種 UI 組件時,有時會非常混亂,不知道每個組件在堆疊 (stack) 中佔用了多少空間。

我們可以選擇某個元素,並在 review 中查看它佔用了多少空間。但這個方法有點麻煩,畢竟我們無法反覆查看它。

我利用了 “debug only background-color” 修飾符來解決這個問題,讓我可以看到視圖的顏色,並正確地作出更改。

extension View {
    func debugOnlyModifier<T: View>(_ modifier: (Self) -> T) -> some View {
        #if DEBUG
        return modifier(self)
        #else
        return self
        #endif
    }
    
    private var colors: [Color] {
        [.blue, .yellow, .green, .red, .brown, .cyan, .gray, .indigo, .mint, .pink, .orange]
    }
    
    func debugOnlyBackground() -> some View {
        debugOnlyModifier {
            $0.background(Rectangle().foregroundColor(colors.randomElement()))
        }
    }
}

你也可以這樣使用這個修飾符:

struct BackgroundColorChange: View {
    let gridItems = [GridItem(.flexible()), GridItem(.flexible(minimum: 20, maximum: 50)), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible(minimum: 10, maximum: 20))]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: gridItems, spacing: 0) {
                
                ForEach(0...100, id: \.self) {
                    Text("\($0)")
                        .padding()
                        .debugOnlyBackground()
                }
            }
        }
    }
}

希望這個方法可以讓你發現 App 的問題。如果你有其他除錯的好方法,請留言與我分享。另外,如果你對 SwiftUI 的技術有興奮,可以閱讀這篇文章。謝謝你的閱讀。

本篇原文(標題:Two SwiftUI Debugging Helpers You Can Start Using Right Away)刊登於作者 Medium,由 Dheeru N 所著,並授權翻譯及轉載。

作者簡介: Dheeru N,開發過不同的 App,興趣是學習新技術,並為 App 分開不同的功能。喜歡到處闖蕩,不怕留下傷疤。

譯者簡介:Kelly Chan-AppCoda 編輯小姐。


此文章為客座或轉載文章,由作者授權刊登,AppCoda編輯團隊編輯。有關文章詳情,請參考文首或文末的簡介。

blog comments powered by Disqus
Shares
Share This