SwiftUI: тип выражения неоднозначен без дополнительного контекста, при передаче ObservableObject между представлениями

Я искал пример хранилища данных в SwiftUI и нашел этот пример.

import SwiftUI
import Combine

class MyDatabase: ObservableObject {
    let didChange = PassthroughSubject<MyDatabase, Never>()

    var contacts: [Contact] = [
        Contact(id: 1, name: "Anna"), Contact(id: 2, name: "Beto"),
        Contact(id: 3, name: "Jack"), Contact(id: 4, name: "Sam")
    ] {
        didSet {
            didChange.send(self)
        }
    }

    struct Contact: Identifiable{
        var id: Int
        var name: String
    }
}

struct ContactsList: View {
    @EnvironmentObject private var database: MyDatabase

    var body: some View {
        NavigationView {
            List($database.contacts) { contact in
                NavigationLink(destination: ContactDetail(contact: contact)) {
                    Text(verbatim: contact.value.name)
                    //here Error 1: Types of expression....
                }
            }
            .navigationBarTitle(Text("Contacts"))
        }
    }
}

struct ContactDetail: View {
    @Binding var contact: MyDatabase.Contact

    var body: some View {
        VStack {
            TextField($contact[\.name])
                .textFieldStyle(.roundedBorder)
                .font(.title)
                .padding()
            //here Error 2: Types of expression....
            Spacer()
        }
        .navigationBarTitle(Text("Edit"), displayMode: .inline)
    }
}

Тем не менее, после тестирования я получил ошибку несколько раз:

Тип выражения неоднозначен без дополнительного контекста

Я также попробовал следующий учебник для того же решения https://mecid.github.io/2019/07/03/managing-data-flow-in-swiftui/ но получил те же ошибки. Что-нибудь изменилось в отношении Bindings в последней бете? Я бегу бета 6

1 ответ

Решение

Кажется, что вы используете ObservableObject как BindableObject, BindableObject заменен с бета 4 (?).

BindableObject заменяется протоколом ObservableObject из инфраструктуры объединения.

didChange изменилось в пользу objectWillChange и он должен быть вызван внутри willChange наблюдатель.

Чтобы не повторяться @Published атрибут синтезирует willChange для тебя.

Вы можете вручную соответствовать ObservableObject, определив издателя objectWillChange, который издается до изменения объекта. Однако по умолчанию ObservableObject автоматически синтезирует objectWillChange и выдает его до изменения любых свойств @Published.

class User: ObservableObject {

    @Published var name: String = ""
    @Published var email: String = ""

}

И использовать @ObservedObject если вы хотите привязку вашего ObservableObject:

struct MyView: View {

    @ObservedObject var user: User = User()

    var body: some View {
        TextField("Name", text: $user.name)
    }

}

Если проблема сохраняется, потому что вы используете @EnvironmentObject попробуйте взглянуть на: изменение на @Published var в @EnvironmentObject не отражается сразу

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