SwiftUI - Невозможно назначить переменную внутри applySingleEvent из Firebase. Возвращает ноль - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь загрузить данные из Firebase в класс моей модели данных QuoteBook внутри observeSingleEvent следующим образом:

struct SceneView: View {
    @Binding var showSceneView: Bool

    var databaseRef : DatabaseReference
    @State var quoteBookDaily : QuoteBook?

    var body: some View {
        ZStack {
            GeometryReader { geometry in
                ZStack {
                    Text(self.quoteBookDaily?.title ?? "Make sure you are connected to the internet").font(Font.custom("ShadowsIntoLight", size:30)).multilineTextAlignment(.center).lineSpacing(5).padding()
                    VStack {
                        HStack {
                            Button(action:{self.backPressed()}) {
                                Image("icons8-back-24").renderingMode(.original).resizable().aspectRatio(contentMode: .fit).frame(width: 24, height: 24, alignment: .leading)
                            }.padding()
                            Spacer()
                            Button(action:{self.takeScreenshot()}) {
                                Image("icons8-screenshot-26").renderingMode(.original).resizable().aspectRatio(contentMode: .fit).frame(width: 26, height: 26, alignment: .leading)
                            }.padding()
                        }
                        Spacer()
                    }
                }
            }
        }.onAppear() {

        }
    }

    init(showSceneView : Binding<Bool>) {
        self._showSceneView = showSceneView
        self.databaseRef = Database.database().reference()
        self.initDataFromFirebase()
    }

    func backPressed() {
        self.showSceneView = false
    }

    func takeScreenshot() {

    }

    func initDataFromFirebase() {
        let quoteBook = QuoteBook() // <--- This is not null

        databaseRef.observeSingleEvent(of: .value, with: {(snapshot) in
            let value = snapshot.value as? NSDictionary
            let msg1 = value?["msg1"] as? String ?? " "
            let msg2 = value?["msg2"] as? String ?? " "
            let msg3 = value?["msg3"] as? String ?? " "
            let msg4 = value?["msg4"] as? String ?? " "
            let msg5 = value?["msg5"] as? String ?? " "
            let msg6 = value?["msg6"] as? String ?? " "
            let msg7 = value?["msg7"] as? String ?? " "
            let msg8 = value?["msg8"] as? String ?? " "
            let msg9 = value?["msg9"] as? String ?? " "
            let msg10 = value?["msg10"] as? String ?? " "
            let msg11 = value?["msg11"] as? String ?? " "
            let name = value?["name"] as? String ?? " "


            quoteBook.msg.append(msg1)
            quoteBook.msg.append(msg2)
            quoteBook.msg.append(msg3)
            quoteBook.msg.append(msg4)
            quoteBook.msg.append(msg5)
            quoteBook.msg.append(msg6)
            quoteBook.msg.append(msg7)
            quoteBook.msg.append(msg8)
            quoteBook.msg.append(msg9)
            quoteBook.msg.append(msg10)
            quoteBook.msg.append(msg11)
            quoteBook.title = name

            self.quoteBookDaily = quoteBook
            print(self.quoteBookDaily!.msg[0]) // So why is this null?? <--- Fatal error : Unexpectedly found nil while unwrapping an Optional value

        })
    }
}

struct SceneView_Previews: PreviewProvider {
    static var previews: some View {
        SceneView(showSceneView : .constant(false))
    }
}

Константа quoteBook, объявленная в initDataFromFirebase, не равна нулю , но когда я присваиваю его self.quoteBookDaily и пытаюсь напечатать одно из его свойств, он выдает ошибку, говоря, что он нулевой. Я не понимаю, почему он говорит, что когда я просто переназначаю ненулевой объект другому объекту, он не должен быть нулевым ...

1 Ответ

0 голосов
/ 18 февраля 2020

Я не могу проверить ваш код, но попробуйте следующее

1) дать начальное значение для @State

@State var quoteBookDaily : QuoteBook? = nil

2) состояния обновления в потоке пользовательского интерфейса

...
quoteBook.title = name

DispatchQueue.main.async {
    self.quoteBookDaily = quoteBook
    print(self.quoteBookDaily!.msg[0])
}

если этого будет недостаточно, потому что здесь может быть какой-то гоночный эффект, то перенесите начальную загрузку в onAppear (потому что @State окончательно связывается с представлением, когда представление помещается в иерархию, поэтому есть вероятность, что ваши данные появляется до того, как quoteBookDaily готов принять их)

}.onAppear() {
    self.initDataFromFirebase()
}
...