You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI自定义代理实现:连接视图与TestManager的方法

How to Implement Custom Delegate in SwiftUI for Your TestManager

Got it, let's walk through how to connect your TestManager with the ContentView and handle delegate callbacks properly—with SwiftUI-specific tweaks for state management, since it works a bit differently than Storyboards.

First, there's a small parsing mismatch we need to fix first, then we'll wire up the delegate step by step.

First: Fix the Model Parsing Bug

I noticed your TestModel defines a text property, but in the parseJson method you're trying to access decodedData.message—this will cause decoding to fail (since NumbersAPI returns a text field). Let's fix that:

struct TestModel: Decodable {
    let text: String
}

// Update the parseJson method in TestManager:
func parseJson(_ jsonData: Data) -> TestModel? {
    let decoder = JSONDecoder()
    do {
        let decodedData = try decoder.decode(TestModel.self, from: jsonData)
        let model = TestModel(text: decodedData.text)
        return model
    } catch {
        delegate?.didFailWithError(error)
        return nil
    }
}

Step 1: Prepare the View for Delegate & State

SwiftUI views are value types (structs), so we need to use @StateObject to keep our TestManager instance alive across view refreshes, and @State to store the data we'll display. We'll also make ContentView conform to TestManagerDelegate.

Update your ContentView like this:

import SwiftUI

struct ContentView: View {
    // Use @StateObject to retain the manager instance (avoids re-creating it on refresh)
    @StateObject private var manager = TestManager()
    // State to hold the trivia text we'll display
    @State private var triviaText = "Test Text"
    // State to show error messages if something goes wrong
    @State private var errorMessage: String?

    var body: some View {
        ZStack{
            Color(.green)
                .edgesIgnoringSafeArea(.all)
            VStack {
                Text(triviaText)
                    .font(.title)
                    .foregroundColor(.white)
                    .padding()
                Button(action: {
                    // Trigger the API call when the button is tapped
                    manager.Get()
                }) {
                    Text("Get number 2")
                        .font(.title)
                        .foregroundColor(.white)
                        .padding()
                        .overlay(RoundedRectangle(cornerRadius: 30)
                            .stroke(Color.white, lineWidth: 5))
                }
                // Show error message if there's an error
                if let errorMessage = errorMessage {
                    Text(errorMessage)
                        .foregroundColor(.red)
                        .padding()
                }
            }
        }
        // Set the delegate once the view is ready
        .onAppear {
            manager.delegate = self
        }
    }
}

// Make ContentView conform to TestManagerDelegate
extension ContentView: TestManagerDelegate {
    func didCorrectlyComplete(_ testName: TestManager, model: TestModel) {
        // API calls run on background threads—update UI state on main thread
        DispatchQueue.main.async {
            triviaText = model.text
            errorMessage = nil
        }
    }

    func didFailWithError(_ error: Error) {
        // Update error state on main thread too
        DispatchQueue.main.async {
            errorMessage = error.localizedDescription
        }
    }
}

Key SwiftUI-Specific Notes

  • @StateObject: We use this for manager because it preserves the instance across view re-renders. A regular var would create a new TestManager every time the view refreshes, breaking the delegate connection.
  • Main Thread Updates: API calls run in the background, so we must update UI state (triviaText, errorMessage) on the main thread to avoid runtime warnings or glitches.
  • Delegate Assignment: We set manager.delegate = self in .onAppear to ensure the delegate is linked once the view is fully loaded.

Test It Out

Tap the "Get number 2" button, and the TestManager will make the API call. When the response comes back, the delegate methods will update the view's state—showing the trivia text or an error message if something goes wrong.

内容的提问来源于stack exchange,提问作者runemonster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:47:42