BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

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      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

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.