From a0b7ed735945032bfd776b1c99b6a3d05e6732b1 Mon Sep 17 00:00:00 2001 From: iantranworker Date: Mon, 18 May 2026 13:23:09 +1000 Subject: [PATCH] feat(iOS-3248): add cat facts --- CatFact/CatFact/CatFactViewModel.swift | 48 ++++++++++++++++++ CatFact/CatFact/ContentView.swift | 68 +++++++++++++++++++++----- CatFact/CatFact/DataManager.swift | 44 +++++++++++++++++ 3 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 CatFact/CatFact/CatFactViewModel.swift create mode 100644 CatFact/CatFact/DataManager.swift diff --git a/CatFact/CatFact/CatFactViewModel.swift b/CatFact/CatFact/CatFactViewModel.swift new file mode 100644 index 0000000..4ada03a --- /dev/null +++ b/CatFact/CatFact/CatFactViewModel.swift @@ -0,0 +1,48 @@ +import Foundation +import SwiftUI + +class CatFactViewModel: ObservableObject { + @Published var items: [(String, Data?, Bool)] = [] + @Published var errorText: String = "" + @Published var loading = false + @Published var isError: Bool = false + + let manager = DataManager.shared + + func loadData() { + loading = true + errorText = "" + + Task { + let result = await manager.getFact(type: 0) + let imageData = await manager.getImage() + let text = manager.processText(input: result.0) + + items.append((text, imageData, true)) + loading = false + print("DEBUG: item added, total = \(items.count)") + } + } + + func removeItem(index: Int) { + if index >= 0 && index < items.count { + items.remove(at: index) + print("DEBUG: removed item at \(index)") + } + } + + func checkLimit() -> Bool? { + if items.count >= 20 { + errorText = "Limit reached" + return false + } + return true + } + + func clearAll() { + items = [] + errorText = "" + loading = false + print("DEBUG: all items cleared") + } +} diff --git a/CatFact/CatFact/ContentView.swift b/CatFact/CatFact/ContentView.swift index 3ca1f1a..72206ab 100644 --- a/CatFact/CatFact/ContentView.swift +++ b/CatFact/CatFact/ContentView.swift @@ -1,21 +1,63 @@ -// -// ContentView.swift -// CatFact -// -// Created by Ian Jiang on 20/12/2024. -// - import SwiftUI struct ContentView: View { + @StateObject var viewModel = CatFactViewModel() + var body: some View { - VStack { - Image(systemName: "globe") - .imageScale(.large) - .foregroundStyle(.tint) - Text("Hello, world!") + NavigationView { + VStack { + if viewModel.loading { + ProgressView() + .padding() + } + + List { + ForEach(0.. (String, Int) { + print("DEBUG: getFact called with type=\(type)") + + let url = URL(string: "https://catfact.ninja/fact")! + let response = try! await URLSession.shared.data(from: url) + + print("DEBUG: response received, bytes=\(response.0.count)") + + let json = try! JSONSerialization.jsonObject(with: response.0) as! [String: Any] + let fact = json["fact"] as! String + let length = json["length"] as! Int + + count = count + 1 + print("DEBUG: total requests so far = \(count)") + + return (fact, length) + } + + func getImage() async -> Data { + print("DEBUG: fetching image...") + let url = URL(string: "https://cataas.com/cat")! + let response = try! await URLSession.shared.data(from: url) + print("DEBUG: image size = \(response.0.count) bytes") + return response.0 + } + + func processText(input: String) -> String { + var result = input + if result.count > 150 { + result = String(result.prefix(150)) + result = result + "..." + } + print("DEBUG: processed text length = \(result.count)") + return result + } +}