What is causing this error?

I used the Xcode template to create a Mac App. I then modified ContentView.swift

import SwiftUI
import MapKit

struct ContentView: View {
    @State private var region = MKCoordinateRegion(
      center: CLLocationCoordinate2D(
        latitude: 0.0,
        longitude: 0.0),
      span: MKCoordinateSpan(
        latitudeDelta: 0.5,
        longitudeDelta: 0.5))

    var body: some View {
        Map(coordinateRegion: $region)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

When I run this code, Xcode reports a runtime error:

Modifying state during view update, this will cause undefined behavior.

It is reported on Thread 1.

This is identified with a purple warning in the issue navigator, but there is no indication of the location of the error in the source code editor.

The actual map coordinates don't matter. I get the same error with different coordinates.

  • Xcode 13.3.1
  • OSX Monterey 12.3.1
  • Mac Mini M1

P.S. When I cut the example code above from Xcode and pasted it into this message, it added extra line breaks between each line (which I manually removed). Is there a way to have the code paste as it was in Xcode?

P.P.S. When I listed the software and hardware info, If I don't make it a bulleted list, the ended up being displayed on one line. If I put blank lines between them, the blank lines are displayed. Is there any way to make a vertical list without bullets?

Answered by MarkErbaugh in 712053022

I figured it out. The warning is correct, the examples in Apple's documentation are incorrect. The following is from the DH entry for Map:

struct AppleParkMap: View {
     
    @State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 37.334_900,
                                       longitude: -122.009_020),
        latitudinalMeters: 750,
        longitudinalMeters: 750
    )
    
    var body: some View {
        Map(coordinateRegion: $region)
    }
}

This code is very similar to what I originally posted. It generates the same error.

The issue is that the region object passed as a binding to the Map() constructor is part of the view's state. The Map object is modifying the binding as it is updating the view which is trying to update the view's state.

The fix that works is to have the region be part of a ViewModel.

class VM: NSObject, ObservableObject {
    @Published var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 37.334_900,
                                       longitude: -122.009_020),
        latitudinalMeters: 750,
        longitudinalMeters: 750
    )
}

struct ContentView: View {
    @State private var vm = VM()
    
    var body: some View {
        Map(coordinateRegion: $vm.region)
    }
}

This code works without the issue.

The easiest questions first:

Is there a way to have the code paste as it was in Xcode?

Yes, use Paste and Match Style in Edit Menu.

 Is there any way to make a vertical list without bullets?

I've not found other ways, except format the 3 lines with code formatter

line 1
line 2
line 3

Not optimal, but the forum editor is not very flexible…

As for the code:

I do not get the error, but spurious messages as described here: https://developer.apple.com/forums/thread/698623

Does your app works correctly ? If so, ignore the warning and check with a future release if it disappears.

I am also seeing the CoreVideo messages reported in the other thread, but I suppress them by adding -cv_note 0 to the startup parameters.

The issue is that this is creating a purple warning triangle in Xcode near the right side of the Xcode window. The warning has < and > indicators to view the previous and next issue. If I click either of those indicators, Xcode crashes. The error log indicates that Xcode is accessing an empty list.

If I remove the call to Map() and re-run, the purple warning at the right side goes away, but one shows up to the right of the Scheme/Title bar at the top of the Xcode window. If I hover over that, the tip is Show Runtime Issues. If I click it it brings up the runtime issues navigator which is empty.

I would like to know what's different about your setup that you are not getting the error message, or what's wrong with my setup.

This is just a code snippet that reproduces the error for me. As to whether it runs correctly or not, that's not the issue. I don't like ignoring log noise in the output window, but if I have to start ignoring runtime issues in the issues navigator, that really reduces the usefulness of the issues navigator.

I recompiled an MapKit app that I wrote a few months ago. It does not show this issue. The app was developed with a previous version of Xcode, but I just compiled it with the current version. No purple error issues.

Accepted Answer

I figured it out. The warning is correct, the examples in Apple's documentation are incorrect. The following is from the DH entry for Map:

struct AppleParkMap: View {
     
    @State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 37.334_900,
                                       longitude: -122.009_020),
        latitudinalMeters: 750,
        longitudinalMeters: 750
    )
    
    var body: some View {
        Map(coordinateRegion: $region)
    }
}

This code is very similar to what I originally posted. It generates the same error.

The issue is that the region object passed as a binding to the Map() constructor is part of the view's state. The Map object is modifying the binding as it is updating the view which is trying to update the view's state.

The fix that works is to have the region be part of a ViewModel.

class VM: NSObject, ObservableObject {
    @Published var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 37.334_900,
                                       longitude: -122.009_020),
        latitudinalMeters: 750,
        longitudinalMeters: 750
    )
}

struct ContentView: View {
    @State private var vm = VM()
    
    var body: some View {
        Map(coordinateRegion: $vm.region)
    }
}

This code works without the issue.

What's the difference though? You have @State region or @State vm - they are both states of the view. If you (Map) update region, it updates the main view's state. If you (Map) update vm, it has a published property, so it also updates the main view's state. In my simple experiment both of these implementations were causing exactly the same warning. Tested with iOS 16. Which makes sense to me, as both versions are doing the same thing - updating state of the main view.

What is causing this error?
 
 
Q