| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- //
- // PetListViewController.swift
- // VenusKitto
- //
- // Created by Neoa on 2025/8/25.
- //
- import Foundation
- import UIKit
- struct Pet: Codable {
- let id: String
- let name: String
- let avatar: String
- let breedName: String
- let age: String
- }
- struct PetListResponse: Codable {
- let code: String
- let msg: String?
- let data: [Pet]
- }
- class PetListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
-
- private var pets: [Pet] = []
- var onPetSelected: ((Pet) -> Void)?
- func reloadPetList() {
- tableView.reloadData()
- }
-
- private let tableView = UITableView()
- private var selectedPet: Pet?
- override func viewDidLoad() {
- super.viewDidLoad()
-
- // Set up table view
- tableView.delegate = self
- tableView.dataSource = self
- tableView.register(PetTableViewCell.self, forCellReuseIdentifier: "PetCell")
-
- view.addSubview(tableView)
- tableView.translatesAutoresizingMaskIntoConstraints = false
- NSLayoutConstraint.activate([
- tableView.topAnchor.constraint(equalTo: view.topAnchor),
- tableView.leftAnchor.constraint(equalTo: view.leftAnchor),
- tableView.rightAnchor.constraint(equalTo: view.rightAnchor),
- tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
- ])
-
- fetchPetList() // Request pet list
- }
-
- // Table view data source
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return pets.count
- }
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let pet = pets[indexPath.row]
- let cell = tableView.dequeueReusableCell(withIdentifier: "PetCell", for: indexPath) as! PetTableViewCell
- cell.configure(with: pet)
- return cell
- }
-
- // Table view delegate
- func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- let selectedPet = pets[indexPath.row]
- onPetSelected?(selectedPet)
- self.dismiss(animated: true)
- // Handle switching pet or showing more details
- }
-
- func fetchPetList() {
- // Get userId from UserDefaults
- guard let userId = UserDefaults.standard.string(forKey: "userId"), !userId.isEmpty else {
- print("⚠️ fetchPetList: userId missing or empty in UserDefaults")
- return
- }
- // Build URL with query parameter
- var components = URLComponents(string: "\(baseURL)/petRecordPet/queryPetList")
- components?.queryItems = [URLQueryItem(name: "userId", value: userId)]
- guard let url = components?.url else {
- print("⚠️ fetchPetList: Failed to build URL with userId param")
- return
- }
- print("🐾 fetchPetList URL: \(url.absoluteString)")
- var request = URLRequest(url: url)
- request.httpMethod = "GET"
- request.setValue("application/json", forHTTPHeaderField: "Content-Type")
- if let token = UserDefaults.standard.string(forKey: "userToken") {
- request.setValue(token, forHTTPHeaderField: "Authorization")
- }
- let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
- if let httpResp = response as? HTTPURLResponse {
- print("🐾 fetchPetList HTTP status: \(httpResp.statusCode)")
- }
- if let error = error {
- print("Error: \(error)")
- return
- }
- guard let data = data else { return }
- do {
- let decoder = JSONDecoder()
- let responseObject = try decoder.decode(PetListResponse.self, from: data)
- if responseObject.code == "200" {
- self?.pets = responseObject.data
- DispatchQueue.main.async {
- self?.reloadPetList()
- }
- } else {
- print("Error: \(responseObject.msg ?? "Unknown error")")
- }
- } catch {
- print("Error decoding response: \(error)")
- }
- }
- task.resume()
- }
- }
- class PetTableViewCell: UITableViewCell {
-
- private let avatarImageView = UIImageView()
- private let nameLabel = UILabel()
- override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
- super.init(style: style, reuseIdentifier: reuseIdentifier)
-
- avatarImageView.contentMode = .scaleAspectFill
- avatarImageView.layer.cornerRadius = 24
- avatarImageView.clipsToBounds = true
- contentView.addSubview(avatarImageView)
-
- nameLabel.font = .systemFont(ofSize: 16)
- contentView.addSubview(nameLabel)
-
- avatarImageView.translatesAutoresizingMaskIntoConstraints = false
- nameLabel.translatesAutoresizingMaskIntoConstraints = false
-
- NSLayoutConstraint.activate([
- avatarImageView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 16),
- avatarImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
- avatarImageView.widthAnchor.constraint(equalToConstant: 48),
- avatarImageView.heightAnchor.constraint(equalToConstant: 48),
-
- nameLabel.leftAnchor.constraint(equalTo: avatarImageView.rightAnchor, constant: 16),
- nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
- ])
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- func configure(with pet: Pet) {
- nameLabel.text = pet.name
- if let url = URL(string: pet.avatar) {
- loadImage(from: url)
- }
- }
-
- private func loadImage(from url: URL) {
- // Create a data task to load the image
- URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
- // Check for errors
- if let error = error {
- print("Error loading image: \(error)")
- return
- }
-
- // Check if data is valid
- guard let data = data else {
- print("No data returned")
- return
- }
-
- // Update the image on the main thread
- DispatchQueue.main.async {
- if let image = UIImage(data: data) {
- self?.avatarImageView.image = image
- }
- }
- }.resume() // Start the download
- }
- }
|