iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Vibe Coding

從零打造 AI 全端應用:Vibe Coding 結合 n8n 視覺化工作流實戰系列 第 8 篇

Day 08:串接前夕:設計前端 API Service 層與 Mock Data 測試

  • 分享至 

  • xImage
  •  

Day 08:串接前夕:設計前端 API Service 層與 Mock Data 測試

嗨,大家今天過得好嗎?歡迎來到鐵人賽 Day 8。

截至昨天為止,我們已經用 Vibe Coding 打造了乾淨的 MVC 架構跟高質感的 SwiftUI 介面。不過,現在點擊「產生推薦菜單」按鈕,Console 只會印出一行可憐的 print("準備發送 API 請求...")。

在真實的全端開發情境中,後端(我們這次是 n8n)通常沒那麼快把 API 寫好。如果我們傻傻地等後端完工才繼續寫前端,專案進度絕對會大 Delay。

所以今天,我們要來做前端開發非常重要的一個步驟:建立 API Service 層與 Mock Data(假資料)機制。

為什麼要抽離 API Service 層?

很多剛學 iOS 或是過度依賴 AI 寫 Code 的人,會把打 API 的程式碼(像是 URLSession、JSONDecoder)全部塞在 Controller 甚至 View 裡面。這絕對是個災難。

想像一下,未來如果 API 網址換了,或是我們要加上 Token 驗證,你總不希望去翻找每一個 Controller 來改吧?所以,我們要把「網路請求」獨立成一個專門的 Service 檔案。Controller 只需要問 Service:「嘿,給我資料」,至於資料是怎麼來的,Controller 不需要、也不應該知道。

定義未來的回傳格式 (Response Model)

在叫 AI 幫我們寫 Service 之前,我們必須先跟未來的後端(n8n)「喬好」資料長什麼樣子。這也是我們要新增的 Model。

請在 Models 資料夾下,新增一個 HardwareMenu.swift:

import Foundation

// 這是我們預期從 n8n 收到的 AI 推薦結果
struct HardwareMenu: Codable {
    let cpu: String
    let gpu: String
    let totalPrice: Int
    let reason: String // AI 給的推薦理由
}

用 Prompt 召喚 Mock Service

現在,我們要請 AI 幫我們建立 API Service 層,並且使用 Mock Data (假資料) 來模擬網路連線。為什麼要模擬?因為這樣我們才能在前端實作「轉圈圈等待 (Loading)」的狀態。

你可以用這段結構化 Prompt 來引導 AI:

我正在開發一個遵循 MVC 架構的 SwiftUI App。
目前已經定義好回傳資料的 Model 如下:
(貼上上面的 HardwareMenu 程式碼)

請幫我新增一個 `APIService.swift`:
1. 請實作一個單例模式 (Singleton) 的 `APIService`。
2. 寫一個非同步函數 `fetchRecommendation(budget:purpose:)`。
3. 【重要】目前後端還沒寫好,請在該函數內實作 Mock Data (假資料)。使用 `Task.sleep` 模擬 2 秒的網路延遲,然後回傳一份寫死的 `HardwareMenu` 假資料。

AI 應該會產出類似這樣乾淨的 Service 檔案(請把它放在專案目錄裡):

// APIService.swift
import Foundation

class APIService {
    // 單例模式,方便全域呼叫
    static let shared = APIService()
    private init() {}
    
    // 非同步函數,回傳我們剛剛定義的 HardwareMenu
    func fetchRecommendation(budget: Int, purpose: String) async throws -> HardwareMenu {
        
        // 模擬真實世界的網路延遲 (等待 2 秒)
        try await Task.sleep(nanoseconds: 2_000_000_000)
        
        // 未來這裡會寫真實的 URLSession 網路請求
        // 目前先回傳寫死的假資料
        return HardwareMenu(
            cpu: "AMD Ryzen 5 7500F",
            gpu: "NVIDIA RTX 4060",
            totalPrice: 28500,
            reason: "針對 \(purpose) 需求,這套配置在預算 \(budget) 元內能提供最佳的 1080p 遊戲體驗,性價比極高。"
        )
    }
}

更新 Controller,把線接起來!

Service 寫好了,現在我們要讓 HomeController 去呼叫它。
打開你的 HomeController.swift,我們需要新增兩個狀態:一個是讓畫面知道「正在讀取中」的 isLoading,另一個是拿來裝「結果」的 resultMenu。

你可以自己改,或是叫 AI 幫你更新:

// HomeController.swift
import Foundation
import SwiftUI // 為了 MainActor

@MainActor // 確保 UI 更新都在主執行緒
class HomeController: ObservableObject {
    @Published var requestData = HardwareRequest()
    @Published var isLoading = false         // 新增:讀取狀態
    @Published var resultMenu: HardwareMenu? // 新增:裝載 API 回傳的結果
    
    let purposeOptions = ["3A 遊戲", "影音剪輯", "文書處理"]
    
    func submitRequest() {
        guard let budgetInt = Int(requestData.budget), budgetInt > 0 else {
            print("請輸入有效的預算金額")
            return
        }
        
        // 1. 開啟讀取狀態
        isLoading = true
        resultMenu = nil
        
        // 2. 開啟非同步 Task 呼叫 API
        Task {
            do {
                let menu = try await APIService.shared.fetchRecommendation(
                    budget: budgetInt, 
                    purpose: requestData.purpose
                )
                // 3. 拿到結果後,更新狀態、關閉讀取
                self.resultMenu = menu
                self.isLoading = false
            } catch {
                print("發生錯誤:\(error)")
                self.isLoading = false
            }
        }
    }
}

小結

把這段寫完後,雖然你的畫面看起來跟昨天一樣,但骨子裡已經完全不同了。

現在只要你按下「產生推薦菜單」,背後就會透過非同步任務 (async/await) 模擬網路連線,等個兩秒鐘後,HomeController 就能成功拿到假資料。我們成功把前端架構的最後一塊拼圖——網路通訊層 (Network Layer) 給獨立出來了。

明天,我們要用 Vibe Coding 完成前端戰場的最後一役:打磨 Loading 狀態,並把這份假資料渲染成一張漂亮的「AI 推薦結果卡片」!

我們 Day 09 見!


上一篇
Day 07:狀態管理不崩潰:引導 AI 建立正確的資料綁定與元件化
下一篇
Day 09:視覺打磨與優化:實作 Loading 轉場與 AI 推薦結果卡片
系列文
從零打造 AI 全端應用:Vibe Coding 結合 n8n 視覺化工作流實戰 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言