Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将内容模型转换为环境对象_Ios_Swift_Swiftui_Contentful - Fatal编程技术网

Ios 将内容模型转换为环境对象

Ios 将内容模型转换为环境对象,ios,swift,swiftui,contentful,Ios,Swift,Swiftui,Contentful,我需要将我的Contentful模型转换为可在多个视图之间访问 例如,我将有一个电影列表&每个电影都有一个图像、标题和一个指向预告片的URL。我将有一个处理图像的视图,当用户点击图像时,我希望更新标题视图&将播放预告片的视图将根据选择进行更新 下面最好的更新方式是什么,这样当我调用selectableRow时,我可以用正确的数据更新我的标题和视频播放器 我尝试将我的电影结构更新为类,并使其成为可观察对象,但这只会导致错误 import SwiftUI import Combine import

我需要将我的
Contentful
模型转换为可在多个视图之间访问

例如,我将有一个电影列表&每个电影都有一个图像、标题和一个指向预告片的URL。我将有一个处理图像的视图,当用户点击图像时,我希望更新标题视图&将播放预告片的视图将根据选择进行更新

下面最好的更新方式是什么,这样当我调用
selectableRow
时,我可以用正确的数据更新我的标题和视频播放器

我尝试将我的
电影
结构更新为类,并使其成为
可观察对象
,但这只会导致错误

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 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 {
                    let urlString = "\(urlBase)\(self.movie.movieId).png?"
                    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 {
                   let urlString = "\(urlBase)\(self.movie.movieId).png?"
                   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 mainView : View {

    @ObservedObject var fetcher = MovieFetcher()

    @State private var show = true

    var body: some View {
        ZStack {
            trailerView(show: $show)
            titleView(show: $show)
            moviesView(show: $show)
        }
    }
}

class hostingController: UIHostingController<mainView> {

    required init?(coder: NSCoder) {
        super.init(coder: coder,rootView: mainView().environmentObject(Movie())); // Getting error here
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
导入快捷界面
进口联合收割机
意味深长
结构电影:可编码、可识别、FieldKeysQueryable、EntryDecodable{
静态let contentTypeId:String=“movies”
//扁平资源成员。
let id:String
var updatedAt:日期?
var createdAt:日期?
var localeCode:String?
变量标题:字符串
var-movieId:String
var movieTrailer:字符串
枚举字段键:字符串、编码键{
案例名称,电影ID,电影制作人
}
枚举编码键:字符串,编码键{
案例id=“id”
案例标题=“标题”
case movieId=“movieId”
case movieTrailer=“movieTrailer”
}
}
公共类电影获取程序:observeObject{
@已发布的var movies=[Movie]()
init(){
getArray(id:“电影”){(项目)位于
items.forEach{(item)在
self.movies.append(电影(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.where(contentTypeId:“电影”)
中的client.fetchArray(of:Movie.self,matching:query){(result:result)
切换结果{
成功案例(let数组):
DispatchQueue.main.async{
完成(数组项)
}
案例错误(let error):
打印(错误)
}
}
}
}
结构电影视图:视图{
@ObservedObject var fetcher=MovieFetcher()
@状态变量selectMovie:电影?=无
@绑定变量显示:Bool
var body:一些观点{
HStack(对齐:。底部){
如果显示{
滚动视图(.horizontal){
垫片()
HStack(对齐:底部,间距:30){
ForEach(fetcher.movies,id:\.self){item in
selectableRow(电影:项目,selectMovie:self.$selectMovie)
}
}
.frame(最小宽度:0,最大宽度:无穷大)
}
.padding(.leading,46)
.padding(.bottom,26)
}
}
}
}
结构selectableRow:视图{
电影:电影
@绑定变量selectedMovie:电影?
@状态变量initialImage=UIImage()
var body:一些观点{
ZStack(对齐:。中心){
如果电影==所选电影{
图像(“”)
.可调整大小()
.框架(宽度:187,高度:254)
.覆盖(
圆角转角(拐角半径:13)
图像(uiImage:initialImage)
.可调整大小()
.转弯半径(13.0)
.框架(宽:182,高:249)
奥纳佩尔先生{
让urlString=“\(urlBase)\(self.movie.movieId).png?”
guard let url=url(字符串:self.urlString)else{return}
URLSession.shared.dataTask(带:url){(数据、响应、错误)在
guard let data=data else{return}
guard let image=UIImage(数据:data)else{return}
RunLoop.main.perform{
self.initialImage=image
}
}1.简历()
}
}否则{
图像(uiImage:initialImage)
.可调整大小()
.转弯半径(13.0)
.框架(宽:135,高:179)
奥纳佩尔先生{
让urlString=“\(urlBase)\(self.movie.movieId).png?”
guard let url=url(字符串:self.urlString)else{return}
URLSession.shared.dataTask(带:url){(数据、响应、错误)在
guard let data=data else{return}
guard let image=UIImage(数据:data)else{return}
RunLoop.main.perform{
self.initialImage=image
}
}1.简历()
}
}
}
.ontapsigne{
self.selectedMovie=self.movie
}
}
}
结构主视图:视图{
@ObservedObject var fetcher=MovieFetcher()
@状态私有变量show=true
var body:一些观点{
ZStack{
trailerView(显示:$show)
标题视图(显示:$show)
moviesView(show:$show)
}
}
}
类hostingController:UIHostingController{
必需初始化?(编码器:NSCoder){
super.init(coder:coder,rootView:mainView().environmentObject(Movie());//此处获取错误
}
重写func viewDidLoad(){
super.viewDidLoad()
}
}

我假设您希望在UIKit项目中使用mainView

不确定您想做什么,但您不能这样做:

required init?(coder: NSCoder) {
        super.init(coder: coder,rootView: mainView().environmentObject(Movie())); // Getting error here
    }

因为您已经有了一个可观察对象(MovieFetcher),所以您可以在mainView或任何其他视图中使用fetcher.movies来访问电影。

我假设您希望在UIKit项目中使用mainView