Инициализация карты из наблюдаемой модели представления в SwiftUI

Я пытаюсь внедрить Map в представление SwiftUI из модели представления. В каждом примере я нахожу в Интернете жесткие коды координаты. В моем случае я инициализирую модель представления с помощью структуры Codable, и я понятия не имею, какой будет координата.

При сборке проекта у меня не возникает проблем с компилятором, но холст дает сбой. Я пробовал закрыть Xcode, очистить производные данные и т. д., Но, похоже, это не решает проблему.

Мы очень ценим любые предложения относительно моей ошибки.

class EarthquakeViewModel: ObservableObject {
    @Published private(set) var quakeData: Feature
    @State var region: MKCoordinateRegion
    
    
    init(quakeData: Feature) {
        self.quakeData = quakeData
        let center = CLLocationCoordinate2D(latitude: quakeData.geometry.coordinates[0],
                                        longitude: quakeData.geometry.coordinates[1])
        let span = MKCoordinateSpan(latitudeDelta: 1.0, longitudeDelta: 1.0)
        region = MKCoordinateRegion(center: center,
                                    span: span)
    }

        public lazy var title: String = {
        quakeData.properties.title
    }()
}

Это мой ContentView:

struct EarthquakeView: View {
    @ObservedObject var viewModel: EarthquakeViewModel
    
    var body: some View {
        VStack {
            Text(viewModel.title)
//            makeMapView()
            Map(coordinateRegion: $viewModel.region)
        }
    }
}

// Я тоже пробовал, но не работает.

extension EarthquakeView {
    @ViewBuilder func makeMapView() -> some View {
        Map(coordinateRegion: $viewModel.region)
    }
}

Обновлять

Это сообщение диагностики. Очистка производных данных с закрытым Xcode, похоже, не решает эту проблему, поэтому я думаю, что моя проблема связана с одним из моих объявлений:

RemoteHumanReadableError: Failed to update preview.

The preview process appears to have crashed.

Error encountered when sending 'render' message to agent.

==================================

|  RemoteHumanReadableError: The operation couldn’t be completed. (BSServiceConnectionErrorDomain error 3.)
|  
|  BSServiceConnectionErrorDomain (3):
|  ==BSErrorCodeDescription: OperationFailed

Обновление 2

Я настроил свою модель данных и добавил из нее вычисляемую переменную региона, поэтому теперь я получаю регион следующим образом:

extension Feature /* Feature is a Codable struct */ {
    var region: MKCoordinateRegion {
        let center = CLLocationCoordinate2D(latitude: geometry.coordinates[0],
                                            longitude: geometry.coordinates[1])
        let span = MKCoordinateSpan(latitudeDelta: 1.0, longitudeDelta: 1.0)
        let region = MKCoordinateRegion(center: center,
                                        span: span)
        
        return region
    }
}

По предложению jnpdx's я обновил регион в моей модели представления до @Published.

class EarthquakeViewModel: ObservableObject {
    `@Published private(set) var quakeData: Feature
    `@Published var region: MKCoordinateRegion
    
    init(quakeData: Feature) {
        self.quakeData = quakeData
        region = quakeData.region
    }
    
    public lazy var title: String = {
        quakeData.properties.title
    }()
}

И, наконец, мой взгляд, а именно:

struct EarthquakeView: View {
    @ObservedObject var viewModel: EarthquakeViewModel
    
    @State var region: MKCoordinateRegion
    
    init(viewModel: EarthquakeViewModel) {
        self.viewModel = viewModel
        _region = State(initialValue: viewModel.region)
    }
    
    var body: some View {
        VStack {
            Text(viewModel.title)
            Map(coordinateRegion: $region)
        }
    }
}

Новая ошибка такова. Закрытие Xcode, перезагрузка, очистка производных данных и т.д., похоже, не решают эту проблему, поэтому я быстро прихожу к выводу, что мне не хватает чего-то базового:

PreviewUpdateTimedOutError: Updating took more than 5 seconds Updating a preview from EarthquakeView_Previews in CombineQuake.app (16766) took more than 5 seconds.

Обновление 3

Предварительная инициализация:

struct EarthquakeView_Previews: PreviewProvider {
    static var previews: some View {
        
        let quakeData = EarthQuakeData(mag: 6.5,
                                       place: "32km W of Sola, Vanuatu",
                                       time: 1388592209000,
                                       updated: 1594407529032,
                                       tz: 660,
                                       url: "https://earthquake.usgs.gov/earthquakes/eventpage/usc000lvb5",
                                       detail: "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=usc000lvb5&format=geojson",
                                       felt: nil,
                                       cdi: nil,
                                       mmi: nil,
                                       alert: nil,
                                       status: "reviewed",
                                       tsunami: 1,
                                       sig: 650,
                                       net: "us",
                                       code: "c0001vb5",
                                       ids: ",pt14001000,at00myqcls,usc000lvb5,",
                                       sources: "pt,at,us",
                                       types: "cap,geoserve,impact-link,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary",
                                       nst: nil,
                                       dmin: 3.997,
                                       rms: 0.76,
                                       gap: 14.0,
                                       magType: "mww",
                                       type: "earthquake",
                                       title: "M 6.5 - 32km W of Sola, Vanuatu")
        let geometry = Geometry(type: "Point",
                                coordinates: [167.249, -13.8633, 187.0])
        let earthquake = Feature(type: "Feature",
                                 properties: quakeData,
                                 geometry: geometry,
                                 id: "usc000lvb5")
        
        let viewModel = EarthquakeViewModel(quakeData: earthquake)
        
        
        EarthquakeView(viewModel: viewModel)
    }
}

Невозможно воспроизвести в Xcode 12.4, хотя мне приходится делать некоторые предположения о вашем коде, поскольку вы не включили Feature или сам предварительный просмотр. Однако сразу же я заметил, что вы используете @State в ObservableObject - вероятно, это должен быть @Published.

jnpdx 08.04.2021 08:19

Спасибо, что посмотрели. Я обновился для вашего предложения. Другая ошибка, по-прежнему нет карты :(

Adrian 08.04.2021 08:51

По-прежнему не воспроизводится для меня (хотя мне все еще нужно сделать некоторые выводы о коде). Можете показать, как вы создаете превью? Работает ли это на симуляторе без предварительного просмотра?

jnpdx 08.04.2021 08:58

Спасибо, что посмотрели. Я обновился с помощью PreviewProvider. Если я закомментирую объявление Map, текст будет отображаться, как ожидалось.

Adrian 08.04.2021 09:07

Код предварительного просмотра не компилируется из-за того, что в коде, который вы здесь включили, отсутствуют все типы, но для меня нет ничего необычного. По-прежнему интересно узнать, происходит ли это только в превью или на сим-карте / устройстве.

jnpdx 08.04.2021 09:10
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы запустите это на симуляторе, а не в предварительном просмотре, вы получите более полезную ошибку:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region <center:+167.24900000, -13.86330000 span:+1.00000000, +1.00000000>'

Я изменился:

let geometry = Geometry(type: "Point",
                                coordinates: [167.249, -13.8633, 187.0])

к

let geometry = Geometry(type: "Point",
                                coordinates: [45, 34, 187.0])

и все работало нормально.

Ваша широта 167,249 выходит за пределы от -90 до 90, что является допустимым диапазоном.

РЖУ НЕ МОГУ. Геологическая служба США отправляет координаты в обратном порядке. Я очень ценю вашу помощь. Спасибо. earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php

Adrian 08.04.2021 09:50

Другие вопросы по теме