【问题标题】:Trouble displaying data from Contentful in SwiftUI在 SwiftUI 中无法显示来自 Contentful 的数据
【发布时间】:2020-06-24 18:31:32
【问题描述】:

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

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

但在我的可选行中,我得到了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
        }
    }
}

【问题讨论】:

    标签: ios swift xcode swiftui contentful


    【解决方案1】:

    我想这是故意的

    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 类型的名称和lowerCased 类型的变量/属性,遵循这一点,您和编译器都不会感到困惑。

    【讨论】:

    • 非常感谢!还有一个问题,我可以使用 SwiftUI 默认选择第 0 项吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 2021-11-23
    • 2017-11-20
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    相关资源
    最近更新 更多