无法在 SwiftUI 中显示来自 Contentful 的数据

Trouble displaying data from Contentful in SwiftUI

我正在尝试将 Contentful 中的数据显示到我的 SwiftUI 应用程序中,但我遇到了问题。

目标是显示电影列表并使其可点击。当我 select 一部电影时,我想获取该电影的数据,例如标题和电影预告片。

但是在我的 selectable 行中我得到了 Use of undeclared type 'movie' 而在我的电影视图中我得到了 Use of undeclared type 'fetcher'

下面是我尝试过的方法:

import SwiftUI
import Combine
import Contentful

struct Movie: Codable, Identifiable, FieldKeysQueryable, EntryDecodable {

    static let contentTypeId: String = "movies"

    // FlatResource Memberes.
    let id: String
    var updatedAt: Date?
    var createdAt: Date?
    var localeCode: String?

    var title: String
    var movieId: String
    var movieTrailer: String

    enum FieldKeys: String, CodingKey {

        case title, movieId, movieTrailer
    }

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case title = "title"
        case movieId = "movieId"
        case movieTrailer = "movieTrailer"
    }
}

public class MovieFetcher: ObservableObject {

    @Published var movies = [Movie]()

    init() {
        getArray(id: "movies") { (items) in
            items.forEach { (item) in
                self.movies.append(Movie(id: item.id, title: item.title, movieId: item.movieId, movieTrailer: item.movieTrailer))
            }
        }
    }

    func getArray(id: String, completion: @escaping([Movie]) -> ()) {

        let client = Client(spaceId: spaceId, accessToken: accessToken, contentTypeClasses: [Movie.self])

        let query = QueryOn<Movie>.where(contentTypeId: "movies")

        client.fetchArray(of: Movie.self, matching: query) { (result: Result<ArrayResponse<Movie>>) in
            switch result {
            case .success(let array):
                DispatchQueue.main.async {
                    completion(array.items)
                }
            case .error(let error):
                print(error)
            }
        }
    }
}

struct moviesView : View {

    @ObservedObject var fetcher = MovieFetcher()

    @State var selectMovie: Movie? = nil

    @Binding var show: Bool

    var body: some View {
        HStack(alignment: .bottom) {
            if show {
                ScrollView(.horizontal) {
                    Spacer()

                    HStack(alignment: .bottom, spacing: 30) {
                        ForEach(fetcher.movies, id: \.self) { item in
                            selectableRow(movie: item, selectMovie: self.$selectMovie)
                        }
                    }
                    .frame(minWidth: 0, maxWidth: .infinity)
                }
                .padding(.leading, 46)
                .padding(.bottom, 26)
            }
        }
    }
}

struct selectableRow : View {

    var movie: Movie

    @Binding var selectedMovie: Movie?

    @State var initialImage = UIImage()

    var urlString = "\(urlBase)\(movie.movieId).png?"

    var body: some View {
        ZStack(alignment: .center) {
            if movie == selectedMovie {
                Image("")
                .resizable()
                .frame(width: 187, height: 254)
                .overlay(
                    RoundedRectangle(cornerRadius: 13)
                Image(uiImage: initialImage)
                .resizable()
                .cornerRadius(13.0)
                .frame(width: 182, height: 249)
                .onAppear {
                    guard let url = URL(string: self.urlString) else { return }
                    URLSession.shared.dataTask(with: url) { (data, response, error) in
                        guard let data = data else { return }
                        guard let image = UIImage(data: data) else { return }

                        RunLoop.main.perform {
                            self.initialImage = image
                        }

                    }.resume()
                }
            } else {
                Image(uiImage: initialImage)
                .resizable()
                .cornerRadius(13.0)
                .frame(width: 135, height: 179)
                .onAppear {
                    guard let url = URL(string: self.urlString) else { return }
                    URLSession.shared.dataTask(with: url) { (data, response, error) in
                        guard let data = data else { return }
                        guard let image = UIImage(data: data) else { return }

                        RunLoop.main.perform {
                            self.initialImage = image
                        }

                    }.resume()
                }
            }
        }
        .onTapGesture {
            self.selectedMovie = self.movie
        }
    }
}

我想这是故意的

struct moviesView : View {

    @ObservedObject var fetcher = MovieFetcher()
    @State var selectMovie: Movie? = nil // type is Movie !!
    ...

这里

struct selectableRow : View {

    var movie: Movie
    @Binding var selectedMovie: Movie? // type is Movie !!

好的做法是对类型使用 Capitalized 名称,对 variables/properties 使用 lowerCased 类型,遵循这一点,您和编译器都不会混淆。