ViewDidLoad не выполняет действия в правильном порядке - Firebase, Swift - PullRequest
0 голосов
/ 09 марта 2019

Когда я пытаюсь запустить следующий код на симуляторе (также на устройстве, результат тот же), у меня возникает проблема: функция выполняет сначала часть 2 следующего кода (комментарии там только для того, чтобы иметьСсылка, сам код полностью находится в viewDidLoad. Просто чтобы прояснить), а затем он выполняет часть 1 (часть Firebase).Мне нужно, чтобы функция ref.child .... была выполнена перед другой функцией, потому что для функции "createAlbums" нужны альбомы, взятые из моей базы данных (поэтому блок завершения будет идеальным, но эта функция не позволяет мне поставитьлюбой).

Я подумал о паре решений:

  1. Способ добавления блока завершения (помните, что ref.child ... func похож нацикл, поэтому он будет печатать весь массив "album" для каждого отдельного значения, которое он найдет в базе данных.

  2. Создайте переменную Int и заставьте часть 2 кода выполняться, только еслизначение переменной равно количеству значений «Альбомов» в базе данных, поэтому оно заполнит локальный массив «Альбомы».

  3. Используйте две разные функции:viewDidLoad и viewDidAppear. Как я знаю, второй будет выполняться после первого.

Какое решение является лучшим? Есть ли лучшее решение? Я также спрашиваю вассделать подсказки о том, как я могуn создавать свои собственные решения, потому что я могу логически прийти к сути, но я не уверен, что смогу разработать их в Xcode.

Просто подведу итог всей теме: как я могу сделать 2 частиследующего кода запустить после 1 части?И почему он запускается раньше, даже если порядок написания правильный и компилятор запускается со строки 1 до последней строки?

Спасибо за вашу помощь и извините за мой плохой английский, я надеюсь, что выЯ могу понять все, но, к сожалению, попытаться объяснить «сложную» проблему на английском языке не всегда легко.

Но я думаю, что модераторы будут великолепны, как всегда, чтобы внести некоторые исправления!

// 1
let ref = Database.database().reference()
var albums: [String] = [String]()

override func viewDidLoad() {
    super.viewDidLoad()
    ref.child("Albums").observe(.childAdded) { (snapshot) in
        albums.append(snapshot.key)

        print("\(albums)")
        print("Test print")
    }

// 2   
    createAlbums()
    setupConstraints()
}

Ответы [ 2 ]

0 голосов
/ 10 марта 2019

ДРУГОЕ РАБОЧЕЕ РЕШЕНИЕ

В этом случае наблюдайте событие .value для той же ссылки / запроса. В вашем замыкании зациклите дочерние элементы, как показано здесь stackoverflow.com/a/27342233, и в конце цикла вызовите createAlbums ().

Из комментария Фрэнка ван Пуффелена

0 голосов
/ 10 марта 2019

Вам нужно будет переместить createAlbums () и setupConstraints () туда, где вы делаете тестовую печать.

Хотя похоже, что ваш код все происходит в одном месте, на самом деле это не так.

Эти строки между фигурными скобками ...

albums.append(snapshot.key)

print("\(albums)")
print("Test print")

... происходит асинхронно, когда firebase перезванивает вам, потому что у него есть данные.

Так что вам нужно что-то вроде этого:

// 1
let ref = Database.database().reference()
var albums: [String] = [String]()

override func viewDidLoad() {
    super.viewDidLoad()
    var createdAlbums = false
    ref.child("Albums").observe(.childAdded) { (snapshot) in
        albums.append(snapshot.key)

        print("\(albums)")
        print("Test print")

        if !createdAlbums {
            // Only run this part once, when we
            // get our first callback from firebase
            self.createAlbums()
            self.setupConstraints()
            createdAlbums = true
        }
    }

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