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

Project 14 bug

Forums > 100 Days of SwiftUI

Hi im getting en error in my code. I tried to use the one from github but it desnt work also :/ Maybe you can find something? I cant move on to challende :/

import SwiftUI

struct EditView: View {
    enum LoadingState {
        case loading, loaded, failed
    }

    @Environment(\.dismiss) var dismiss
    var location: Location
    var onSave: (Location) -> Void

    @State private var name: String
    @State private var description: String

    @State private var loadingState = LoadingState.loading
    @State private var pages = [Page]()

    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Place name", text: $name)
                    TextField("Description", text: $description)
                }

                Section("Nearby…") {
                    switch loadingState {
                    case .loading:
                        Text("Loading…")
                    case .loaded:
                        ForEach(pages, id: \.pageid) { page in
                            Text(page.title)
                                .font(.headline)
                            + Text(": ")
                            + Text(page.description)
                                .italic()
                        }
                    case .failed:
                        Text("Please try again later.")
                    }
                }
            }
            .navigationTitle("Place details")
            .toolbar {
                Button("Save") {
                    var newLocation = location
                    newLocation.id = UUID()
                    newLocation.name = name
                    newLocation.description = description

                    onSave(newLocation)
                    dismiss()
                }
            }
            .task {
                await fetchNearbyPlaces()
            }
        }
    }

    init(location: Location, onSave: @escaping (Location) -> Void) {
        self.location = location
        self.onSave = onSave

        _name = State(initialValue: location.name)
        _description = State(initialValue: location.description)
    }

    func fetchNearbyPlaces() async {
        let urlString = "https://en.wikipedia.org/w/api.php?ggscoord=\(location.coordinate.latitude)%7C\(location.coordinate.longitude)&action=query&prop=coordinates%7Cpageimages%7Cpageterms&colimit=50&piprop=thumbnail&pithumbsize=500&pilimit=50&wbptterms=description&generator=geosearch&ggsradius=10000&ggslimit=50&format=json"

        guard let url = URL(string: urlString) else {
            print("Bad URL: \(urlString)")
            return
        }

        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            let items = try JSONDecoder().decode(Result.self, from: data)
            pages = items.query.pages.values.sorted()
            loadingState = .loaded
        } catch {
            loadingState = .failed
        }
    }
}

struct EditView_Previews: PreviewProvider {
    static var previews: some View {
        EditView(location: Location.example) { _ in }
    }
}

1      

What is the "bug" or error message? Might help us to solve it.

1      

Oh! Right!

Generic struct 'StateObject' requires that 'ContentView.ViewModel' conform to 'ObservableObject'

In line:

 @StateObject private var viewModel = ViewModel()

I tried to use Paul's code from https://github.com/twostraws/HackingWithSwift/tree/main/SwiftUI/project14 But it seems different from the one in tutorial. MAybe its a little older.

1      

I assume you mean the error is happening in ContentView and not in the EditView code you posted.

@StateObject private var viewModel = ViewModel() is just another older way of intialising the viewModel. That would require your viewModel class to conform to ObservableObject like so:

class ViewModel: ObservableObject

However in the iOS 17 way, you can simply use

 @Observable
 class ViewModel

and in your view code, simply do this:

@State private var viewModel = ViewModel()

1      

Hi

you are right. I posted EditView instead od ContentView...i'm sorry.

I've already had @Observable class ViewModel in my ContentView - ViewModel.swift

I changed code like you suggested and now new error: Value of type 'Binding<ContentView.ViewModel>' has no dynamic member 'mapRegion' using key path from root type 'ContentView.ViewModel'

1      

Could you post your view and view model code for content view here so it'll be easier to debug?

1      

@swiftasroy I've tried many times but each time i got this message from this website: Your post was disallowed as spam.

1      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

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

Reply to this topic…

You need to create an account or log in to reply.

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.