Swift:尽管将正确的组传递给视图,但在 ViewModel 中获取的拼车 ID 不正确

问题描述 投票:0回答:1

问题概述: 我正在开发一个 SwiftUI 应用程序,我需要在其中获取特定组(拼车)的事件。问题是 CalendarCell 视图无法正确获取所选组的事件。相反,尽管将正确的 GroupT 对象(其中包括正确的拼车 ID)传递给视图,它始终会获取默认组的事件。

预期行为: 当我选择拼车(由 GroupT 表示)时,我希望 CalendarCell 视图使用所选组的拼车 ID 来获取事件。但是,EventViewModel 中使用的拼车 ID 与所选组不匹配。相反,它始终显示最新的组。我正在使用 UserDefaults 来获取我的拼车 ID。

日历单元格视图:

struct CalendarCell: View {
    let group: GroupT
    @StateObject var eventViewModel: EventViewModel
    @State private var events: [Event] = []
    @State private var isShowingDailyEventPage = false

    init(group: GroupT) {
        self.group = group
        _eventViewModel = StateObject(wrappedValue: EventViewModel(group: group))  // Initialize EventViewModel with selected group
    }

    var body: some View {
        Text("Some Day")
            .onTapGesture {
                fetchDailyEvents()
            }
    }

   func fetchDailyEvents() {
        guard let carpoolIDString = UserDefaults.standard.string(forKey: "carpoolID") else {
            print("Carpool ID not found in UserDefaults")
            return
        }
        let joinCode = group.joinCode
        printCarpoolID()
        print("Retrieved Carpool ID from UserDefaults: \(carpoolIDString)")

        guard let carpoolID = UUID(uuidString: carpoolIDString) else {
            print("Invalid UUID string for Carpool ID: \(carpoolIDString)")
            return
        }

        print("Valid Carpool ID: \(carpoolID.uuidString)")

        let viewModel = EventViewModel(group: GroupT(carpoolID: carpoolID, carpoolName: "Example", admin: "admin", date_created: Date(), members: [], events: [], joinCode: joinCode))
        
        viewModel.fetchDailyEvents(forCarpoolID: carpoolID.uuidString, date: dateForCell()) { result in
            switch result {
            case .success(let events):
                DispatchQueue.main.async {
                    self.events = events
                }
            case .failure(let error):
                print("Error fetching events: \(error)")
            }
        }
    }

EventViewModel 功能:

func fetchDailyEvents(forCarpoolID carpoolID: String, date: Date, completion: @escaping (Result<[Event], Error>) -> Void) {
        // DateFormatter for the date string in ISO 8601 format
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd" // API expects this date format
        let dateString = dateFormatter.string(from: date)

        // Lowercase carpoolID for consistency
        let lowercasedCarpoolID = carpoolID.lowercased()

        // Debugging: Print carpool ID and formatted date
        print("Fetching events for Carpool ID: \(lowercasedCarpoolID) on Date: \(dateString)")

        // Construct the API URL
        guard let apiURL = URL(string: "http://localhost/api/events/\(lowercasedCarpoolID)/date/\(dateString)") else {
            print("Invalid API URL")
            completion(.failure(NetworkError.invalidRequest))
            return
        }

        // Debugging: Print the constructed API URL
        print("Constructed API URL: \(apiURL)")

        // Create URLRequest
        var request = URLRequest(url: apiURL)
        request.httpMethod = "GET"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        // Perform the network request
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            // Handle potential errors
            if let error = error {
                print("Network error: \(error.localizedDescription)")
                completion(.failure(NetworkError.invalidResponse))
                return
            }

            // Print the HTTP response status code
            if let httpResponse = response as? HTTPURLResponse {
                print("HTTP Response Status Code: \(httpResponse.statusCode)")
            }

            // Ensure data is not nil
            guard let data = data else {
                print("No data received")
                completion(.failure(NetworkError.invalidResponse))
                return
            }

            // Debugging: Print the raw JSON response
            if let jsonString = String(data: data, encoding: .utf8) {
                print("Received JSON: \(jsonString)")
            }

            do {
                // Decode the response as an array of Event
                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .iso8601 // API uses ISO 8601 for date and time

                // Attempt decoding
                let events = try decoder.decode([Event].self, from: data)

                // Debugging: Print the decoded events
                print("Successfully decoded events: \(events)")
                completion(.success(events))
            } catch {
                // Print detailed decoding error information
                print("Decoding error: \(error.localizedDescription)")
                completion(.failure(error))
            }
        }
        task.resume()
    }

集团结构:

struct GroupT: Codable {
    let carpoolID: UUID
    let carpoolName: String
    let admin: String
    var members: [String]
    let date_created: Date
    let events: [Event]
    let joinCode: String
}

我尝试过的:

  1. 我确保传递到 CalendarCell 的组是正确选择的组。
  2. 我在 fetchDailyEvents 方法中打印 carpoolID 以确认它是正确的。
  3. 尽管如此,视图中仍然使用了错误的组(最新的组),并且为错误的拼车 ID(最近创建的拼车)获取事件。
  4. 我确保拼车 ID 正确保存在 userDefaults 中,它们只是获取不正确。

问题: 如何确保在获取特定组的事件时使用正确的拼车 ID,以及为什么 EventViewModel 没有反映所选组的拼车 ID?

swift xcode swiftui struct userdefaults
1个回答
0
投票
  • 将 EventsViewModel 重命名为 EventsFetcher
  • 将状态事件移动到 EventFetcher 内的已发布属性。
  • 将 fetchDailyEvents 移至 Fetcher

类似这样的:

struct CalendarCell: View {
    let group: GroupT
    @StateObject var eventsFetcher = EventFetcher()
    @State private var isShowingDailyEventPage = false

    var body: some View {
        // display eventsFetcher.events
        Text("Some Day")
            .onTapGesture {
                eventsFetcher.fetchDailyEvents(group)
            }
    }

   
        
     

© www.soinside.com 2019 - 2024. All rights reserved.