TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Day 72: Can't resolve runtime error

Forums > 100 Days of SwiftUI

Hello everyone. I am at the end of the BucketList app creation days and I am struggling to resolve a runtime error. In the video it is expected that one will show up ("Publishing changes from within view updates is not allowed, this will cause undefined behavior.") both in the console and as a purple exclamation point.

However, even after implementing the fix using @MainActor I cannot clear the purple exclamation warning and now a different message is shown in the console:

2022-10-20 09:43:15.490956-0700 BucketList[27327:11286470] [VKDefault] Missing MeshRenderables for ground mesh layer for (4/4) of ground tiles. Tile debug info: (Key: 4.2.3.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 3, PendingMaterial count: 3, Invisible MeshInstances count: 0 | Key: 4.3.3.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 3, PendingMaterial count: 3, Invisible MeshInstances count: 0 | Key: 3.2.3.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 3, PendingMaterial count: 3, Invisible MeshInstances count: 0 | Key: 3.3.3.255 t:34 kt:0, Has mesh errors: 0, MeshInstance count: 2, PendingMaterial count: 2, Invisible MeshInstances count: 0)

This seems like a totally different runtime error than the one highlighted by Paul in the video. The other major difference with this one is that when I click the purple exclamation it does reveal it in the sidebar, but clicking it in the sidebar does not reveal it in the code. So I don't even know where to look.

Anyways, here is my code for ContentView and ContentView-ViewModel. Please let me know if I should post something else:

Note: Googling this console message only gives me results about installing kitchen and bathroom tiles 🤪

struct ContentView: View {
    @StateObject private var viewModel = ViewModel()

    var body: some View {
        if viewModel.isUnlocked {
            ZStack {
                Map(coordinateRegion: $viewModel.mapRegion, annotationItems: viewModel.locations) { location in
                    MapAnnotation(coordinate: location.coordinate) {
                        VStack {
                            Image(systemName: "star.circle")
                                .resizable()
                                .foregroundColor(.red)
                                .frame(width: 44, height: 44)
                                .background(.white)
                                .clipShape(Circle())

                            Text(location.name)
                                .fixedSize()
                        }
                        .onTapGesture {
                            viewModel.selectedPlace = location
                        }
                    }
                }
                .ignoresSafeArea()

                Circle()
                    .fill(.blue)
                    .opacity(0.3)
                    .frame(width: 32, height: 32)

                VStack {
                    Spacer()

                    HStack {
                        Spacer()

                        Button {
                            viewModel.addLocation()
                        } label: {
                            Image(systemName: "plus")
                        }
                        .padding()
                        .background(.black.opacity(0.75))
                        .foregroundColor(.white)
                        .font(.title)
                        .clipShape(Circle())
                        .padding(.trailing)
                    }
                }
            }
            .sheet(item: $viewModel.selectedPlace) { place in
                EditView(location: place) { newLocation in
                    viewModel.update(location: newLocation)
                }
            }
        } else {
            Button("Unlock Places") {
                viewModel.authenticate()
            }
            .padding()
            .background(.blue)
            .foregroundColor(.white)
            .clipShape(Capsule())
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
import Foundation
import LocalAuthentication
import MapKit

extension ContentView {
    @MainActor class ViewModel: ObservableObject {
        @Published var mapRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 50, longitude: 0), span: MKCoordinateSpan(latitudeDelta: 25, longitudeDelta: 25))
        @Published private(set) var locations: [Location]
        @Published var selectedPlace: Location?
        @Published var isUnlocked = false

        let savePath = FileManager.documentsDirectory.appendingPathComponent("SavedPlaces")

        init() {
            do {
                let data = try Data(contentsOf: savePath)
                locations = try JSONDecoder().decode([Location].self, from: data)
            } catch {
                locations = []
            }
        }

        func save() {
            do {
                let data = try JSONEncoder().encode(locations)
                try data.write(to: savePath, options: [.atomic, .completeFileProtection])
            } catch {
                print("Unable to save data.")
            }
        }

        func addLocation() {
            let newLocation = Location(id: UUID(), name: "New location", description: "", latitude: mapRegion.center.latitude, longitude: mapRegion.center.longitude)
            locations.append(newLocation)
            save()
        }

        func update(location: Location) {
            guard let selectedPlace = selectedPlace else { return }

            if let index = locations.firstIndex(of: selectedPlace) {
                locations[index] = location
                save()
            }
        }

        func authenticate() {
            let context = LAContext()
            var error: NSError?

            if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
                let reason = "Please authenticate yourself to unlock your places."

                context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in
                    if success {
                        Task { @MainActor in
                            self.isUnlocked = true
                        }
                    } else {
                        // Error
                    }
                }
            } else {
                // No biometrics
            }
        }
    }
}

3      

Hacking with Swift is sponsored by String Catalog.

SPONSORED Get accurate app localizations in minutes using AI. Choose your languages & receive translations for 40+ markets!

Localize My App

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.