Ulukbek Abylbekov
Ulukbek Abylbekov

Reputation: 459

How to initialize data in Preview provider in SwiftUI

I am trying to fetch data from localhost, make a list of posts with List View and pass data to CustomDetailView. Here is my code for NetworkManager: enter image description here

My ListView: enter image description here

And StoryDetails View: enter image description here

So what I have to pass to StoryDeatils_Preview?

Here is the StoryDetails code

import SwiftUI

struct StoryDetails: View {
    var story: Story
    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Text("story #123456")
                    .font(.callout)
                    .foregroundColor(Color.gray)
                Spacer()
                Text("5 days ago")
                    .font(.callout)
                    .foregroundColor(Color.gray)
                Button(action:{
                    print("Hello there")
                }){
                    Image(systemName:"info.circle").resizable()
                        .frame(width:22.0, height:22.0)
                        .accentColor(Color.gray)
                }
            }
            Text(story.body)
                .foregroundColor(.black)
                .kerning(1)
                .lineLimit(nil)
            HStack {
                Button(action: {
                    print("Hello World")
                }){
                    HStack {
                        Image(systemName:"heart")
                            .accentColor(.black)
                        Text("233")
                            .foregroundColor(.black)
                    }
                    .padding(.trailing)
                    HStack {
                        Image(systemName:"bubble.left")
                            .accentColor(.black)
                        Text("45")
                            .foregroundColor(.black)
                    }
                }
            }
        }
    }   
}

struct StoryDetails_Previews: PreviewProvider {
    static var previews: some View {
        StoryDetails(
            story: Story(
                id: 1,
                author: 1,
                body: "Testing",
                edited_time: "September 2019",
                pub_date: "October 2018",
                comments: [Comment](),
                story_likes: [StoryLike]()
             )
        )
    }
}

Error: enter image description here

Upvotes: 2

Views: 8597

Answers (1)

fakiho
fakiho

Reputation: 521

Hi there first I need to see the StoryDetails() but if StoryDetails a Story it should be declared inside as var story: Story let me explain more in example code: Here you can see my network manager class:

class NetworkManager: ObservableObject {
    let url: String = "https://jsonplaceholder.typicode.com/todos/1"
    var objectWillChange = PassthroughSubject<NetworkManager, Never>()

    init() {
        fetchData()
    }

    @Published var user: User? {
        didSet {
            objectWillChange.send(self)
            print("set user")
        }
    }
    func fetchData() {
        guard let url = URL(string: url) else {return}
        print("fetch data")
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard error == nil else {return}
            print("no error")
            guard let data = data else {return}
            print("data is valid")
            let user = try! JSONDecoder().decode(User.self, from: data)
            DispatchQueue.main.async {
                self.user = user
            }
        }.resume()
    }
}

that's my content view where network manager is initialized inside:

struct ContentView: View {

    @ObservedObject var networkManager = NetworkManager()
    var body: some View {
        VStack {
            DetailsView(user: networkManager.user)
        }
    }
}

Details view struct holds user variable:

struct DetailsView: View {
    var user: User?
    var body: some View {
        VStack {
            Text("id: \(user?.id ?? 0)")
            Text("UserID: \(user?.userId ?? 0 )")
            Text("title: \(user?.title ?? "Empty")")
        }
    }
}

and that's the DetailsView as you can see inside of this struct I declared a user object of type User need to be pass it so if I want to show it in PreviewProvider it would be like the code below

struct DetailsView_Previews: PreviewProvider {
    static var previews: some View {
        DetailsView(user: User(id: 0, userId: 0, title: "hello", completed: false)
    }
}

model:

struct User: Decodable {
    var userId: Int = 0
    var id: Int = 0
    var title: String = ""
    var completed: Bool = false
}

PS: For sure you can unwrap better than this way to provide any nil exception it's just POC

Upvotes: 4

Related Questions