UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Example data shown

Forums > SwiftUI

My app gets a picture and associated data from the internet. When run, the app shows the example data and picture for a second or so, and then shows the data and image I am expecting. I do not want to show the example image and data. Here is part of the program .

import SwiftUI

struct ContentView: View {
    @State var picture: Picture

    var body: some View {
        VStack(alignment: .leading) {
            Text(picture.title)
                .font(.headline)
            PictureView(picture: picture)
        }
        .task {
            await fetchMessages()
        }
    }

    func  fetchMessages() async {
        do {
            let url = URL(string: "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")!
            let (data, _) = try await URLSession.shared.data(from: url)

            let decoder = JSONDecoder()
            picture = try decoder.decode(Picture.self, from: data)
        } catch {
            print("download failed")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(picture: Picture.example)
    }
}

2      

Do you have default values for picture and picture.title? If so, replace them with reasonable values while fetching the data. A more advanced approach would be to check the state of your fetchMessages and adapt your values accordingly.

As a HWS+ member you have access to https://www.hackingwithswift.com/plus/ultimate-portfolio-app/cleaning-up-cloudkit-part-1.

This video should only give you hints how to implement a loading state and can't be used 1:1 for your use case.

2      

sorry I am probably not explaining myself very well. I want to stop the example image and data from showing when the app runs. Viewing the sample image is expected and fine whilst designing the screen, but I cannot see why it shows for a brief time when the app runs.

2      

(See Below)

Bear in mind that you are download data and if it takes a while user may not know what happening.

If you do something like this which will overlay a view as it download it

struct ContentView: View {
    // Set picture to nil
    @State var picture: Picture? = nil

    var body: some View {
        VStack {
            if let picture = picture { // see if picture has data
                Text(picture.title)
                    .font(.headline)
                PictureView(picture: picture)
            } else { // picture has no data
                ProgressView() {
                    Text("Downloading…")
                }
                .scaleEffect(2)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(.ultraThinMaterial)
            }
        }
        .task {
            await fetchMessages()
        }
    }

    func  fetchMessages() async {
        do {
            let url = URL(string: "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")!
            let (data, _) = try await URLSession.shared.data(from: url)

            let decoder = JSONDecoder()
            picture = try decoder.decode(Picture.self, from: data)
        } catch {
            print("download failed")
        }
    }
}

2      

I still think that Picture has the sample values as default values. Otherwise, the code in the first post wouldn't work and crash if picture was nil. So I doubt the solution works.

2      

It will first show what you pass in to ContentView from App

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView(picture: .example)
        }
    }
}

By making @State var picture: Picture? = nil then it work as expected

2      

Yes, I know. But we don't know what is passed into ContentView and according to the code in the first post something has to be passed into ContentView. Otherwise, it wouldn't compile or crash when picture was nil. So, unless the calling part is not changed your code example wouldn't help because picture isn't nil and we should see the same effect unless the network call is done.

That's why I asked are there any default values in Picture set and these are shown for the short period of time?

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.