Ошибка быстрой структуры (невозможно использовать изменяющийся член для неизменного значения: «self» является неизменным) с использованием Firebase - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть пользовательский struct с именем myObjectHolder, и он имеет массив пользовательских struct (называемых myObject) с именем myArray.

Я пытаюсь получить данные, которые храню в Firebase-Firesrtore и добавить его в массив (используя функцию, которая преобразует документ Firebase в myObject).

Я пытаюсь сделать это так:

struct myObjectHolder {
    var myArray = [myObject]()


    private func fetchMyObjects() {
        let db = Firestore.firestore().collection("myObjects").getDocuments { (querySnapshot, err) in
        for document in querySnapshot!.documents {
            self.myArray.append(self.myObjectFromDocument(document: document)) //Error
        }
    }
}

Почему-то, когда я пытаюсь добавить новый myObject к myArray, я получаю это сообщение об ошибке:

Cannot use mutating member on immutable value: 'self' is immutable

Кто-нибудь знает, как я могу решить это? (Я использую SwiftUI это имеет значение)

Спасибо!

Ответы [ 3 ]

2 голосов
/ 25 апреля 2020

Использование класса вместо struct - это одно решение - и если вы думаете, что struct подходит вашему дизайну, используйте

struct myObjectHolder {
    var myArray = [myObject]()


    private mutating func fetchMyObjects() {
        let db = Firestore.firestore().collection("myObjects").getDocuments { (querySnapshot, err) in
        for document in querySnapshot!.documents {
            self.myArray.append(self.myObjectFromDocument(document: document)) //Error
        }
    }
}
0 голосов
/ 25 апреля 2020

То, что другие говорили раньше, верно: вы не можете изменить структуру, поэтому вы должны использовать класс - или сделать структуру модифицируемой. Для получения более подробной информации, ознакомьтесь с https://chris.eidhof.nl/post/structs-and-mutation-in-swift/

Поскольку вы упомянули Firestore специально, позвольте мне предложить вам использовать архитектуру MVVM:

Положите логи доступа к данным c в модель представления:

import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift

class ThingViewModel: ObservableObject {
  @Published var things = [Thing]()

  private var db = Firestore.firestore()

  func fetchData() {
    db.collection("things").addSnapshotListener { (querySnapshot, error) in
      guard let documents = querySnapshot?.documents else {
        print("No documents")
        return
      }

      self.things = documents.map { queryDocumentSnapshot -> Thing in
        return queryDocumentSnapshot.data(as: Thing.self)
      }
    }
  }
}

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

struct ThingsListView: View {
  @ObservedObject var viewModel = ThingsViewModel()

  var body: some View {
    NavigationView {
      List(viewModel.things) { thing in
        VStack(alignment: .leading) {
          Text(thing.name)
            .font(.headline)
        }
      }
      .navigationBarTitle("Things")
      .onAppear() {
        self.viewModel.fetchData()
      }
    }
  }
}

Кроме того, рекомендуется использовать UpperCamelCase для структур и классов Swift: https://github.com/raywenderlich/swift-style-guide#naming

0 голосов
/ 25 апреля 2020

Я только что изменил его с struct на class, и он отлично работал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...