对象don';在SwiftUI上调用Api后,无法更新

对象don';在SwiftUI上调用Api后,无法更新,swift,mvvm,swiftui,environment,Swift,Mvvm,Swiftui,Environment,我正在尝试做一个简单的SwiftUI应用程序来获取最近的电影首映 尝试跟随MVVM并找到了一些教程来进行Api调用,但他们将Api调用放在了模型上 因此,我尝试创建一个服务类和一个状态类来处理@Observed对象问题是,当我尝试查看电影细节时,细节不会加载,但当我尝试另一部电影时,细节是最后一部电影的 这是我的电影服务 public class MoviesService { private let apiKey = "?api_key=" + &quo

我正在尝试做一个简单的SwiftUI应用程序来获取最近的电影首映

尝试跟随MVVM并找到了一些教程来进行Api调用,但他们将Api调用放在了模型上

因此,我尝试创建一个服务类和一个状态类来处理@Observed对象问题是,当我尝试查看电影细节时,细节不会加载,但当我尝试另一部电影时,细节是最后一部电影的

这是我的电影服务

public class MoviesService {
    
    private let apiKey = "?api_key=" + "xxx"
    private let baseAPIURL = "https://api.themoviedb.org/3/movie/"
    private let language = "&language=" + "es-MX"
    
    var nextPageToLoad =  1
    
    var nowPlayingMovies = [Movie]()
    var movieDetail : MovieDetail?
    
    
    init() {
        loadNowPlaying()
    }
        
    func loadNowPlaying(){
  
        let urlString = "\(baseAPIURL)now_playing\(apiKey)\(language)&page=\(nextPageToLoad)"
        print(urlString)
        let url = URL(string: urlString)!
        let request = URLRequest(url: url)
        
        let task = URLSession.shared.dataTask(with: request, completionHandler:parseMovies(data:response:error:))
        task.resume()
    }
    
    func parseMovies(data: Data?, response: URLResponse?, error: Error?){
            var NowPlayingMoviesResult = [Movie]()
            if let data = data {
                if let decodedResponse = try? JSONDecoder().decode(NowPlaying.self, from: data) {
                    // we have good data – go back to the main thread
                    DispatchQueue.main.async { [self] in
                        // update our UI
                      
                        NowPlayingMoviesResult = decodedResponse.results!
                        self.nextPageToLoad += 1
                        
                        for movie in NowPlayingMoviesResult {
                            nowPlayingMovies.append(movie)
                        }
                    }
                    // everything is good, so we can exit
                    return
                }
            }
            
            // if we're still here it means there was a problem
            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
        
    }
    
    func loadDetailMovie(id : Int) {
        
        let urlString = String("\(baseAPIURL)\(id)\(apiKey)\(language)")
        let url = URL(string: urlString)!
        let request = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: request, completionHandler:parseDetailMovie(data:response:error:))
        task.resume()
         
    }
    
    func parseDetailMovie(data: Data?, response: URLResponse?, error: Error?){
            
            if let data = data {
                if let decodedResponse = try? JSONDecoder().decode(moviesApp.MovieDetail.self, from: data) {
                    // we have good data – go back to the main thread
                    DispatchQueue.main.async {
                        self.movieDetail  = decodedResponse
                    }
                    // everything is good, so we can exit
                    return
                }
            }
            
            // if we're still here it means there was a problem
            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
        
    }
 }
这是我的国家班

class StateController: ObservableObject, RandomAccessCollection {
    
    typealias Element = Movie
    
    @Published var movies = [Movie]()
    
    @Published var movie : MovieDetail?
    
    private let moviesService = MoviesService()
    
  
    func shouldLoadMoreData(item : Movie? = nil) -> Bool {
        
        if item == movies.last {
           return true
        }
        return false
    }
    
    func reloadMovies(item : Movie? = nil){
        DispatchQueue.main.async {
            if self.shouldLoadMoreData(item: item) {
                self.moviesService.loadNowPlaying()
            }
            self.movies = self.moviesService.nowPlayingMovies
        }
    }
    
    
    func loadMovieDetails(id: Int){
        DispatchQueue.main.async {
            self.moviesService.loadDetailMovie(id: id)
            self.movie = self.moviesService.movieDetail
        }
    }
    
    var startIndex: Int { movies.startIndex }
    var endIndex: Int { movies.endIndex }
    
    
    subscript(position: Int ) -> Movie {
        return movies[position]
    }
    
}

这是我的电影细节视图

import SwiftUI

struct MovieDetailView: View {
    
    @EnvironmentObject private var stateController: StateController
    @State var id : Int
 
    var body: some View {
        DetailMovieContent(movie: $stateController.movie)
            .onAppear{
                stateController.loadMovieDetails(id: id)
            }
    }
}
这就是我的问题

我做的很好? 使用MVVM和SwiftUI进行make和Api调用的正确方法是什么


您似乎发布了敏感/私人信息。如果是这种情况,请重置密码和/或撤销API密钥和令牌,因为它们在互联网上发布时被视为已被泄露。谢谢,这只是API的密钥,但不是什么大问题。