Ios 如何在ViewDidLoad之前完成函数
我相当确定我从Firebase获取数据的功能工作正常,但是我无法在ViewController中显示数据。看起来视图是在函数完成之前呈现的 在呈现视图之前,我需要帮助了解如何运行该函数 这是viewController中的代码Ios 如何在ViewDidLoad之前完成函数,ios,swift,firebase,firebase-realtime-database,uiviewcontroller,Ios,Swift,Firebase,Firebase Realtime Database,Uiviewcontroller,我相当确定我从Firebase获取数据的功能工作正常,但是我无法在ViewController中显示数据。看起来视图是在函数完成之前呈现的 在呈现视图之前,我需要帮助了解如何运行该函数 这是viewController中的代码 import UIKit import Firebase import Kingfisher class activityVC: UIViewController { // Variables passed from feedVC var activi
import UIKit
import Firebase
import Kingfisher
class activityVC: UIViewController {
// Variables passed from feedVC
var activityId = ""
@IBOutlet weak var distance: UILabel!
@IBOutlet weak var time: UILabel!
@IBOutlet weak var elevation: UILabel!
@IBOutlet weak var kills: UILabel!
@IBOutlet weak var sightings: UILabel!
@IBOutlet weak var ration_shot_sightings: UILabel!
@IBOutlet weak var activityImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Get userdata from Firebase
DataService.instance.getActivityData(activityId: activityId) { (activityData) in
print("activity data dump in ViewController")
dump(activityData)
if activityData.isEmpty == false {
print("Data is coming")
// if data exist populate textfields with information from database
self.kills.text = activityData[0].name
self.sightings.text = String(activityData[0].sightingCount)
print("SightingsCount: \(activityData[0].sightingCount)")
self.kills.text = String(activityData[0].killCount)
self.sightings.text = String(activityData[0].sightingCount)
if activityData[0].defaultImageURL.isEmpty == false {
self.activityImageView.kf.setImage(with: URL.init(string:activityData[0].defaultImageURL))
}
}
}
}
// ----------------------------
// IBActions
// ----------------------------
@IBAction func backBtnWasPressed(_ sender: Any) {
// Navigates back to feedVC
self.dismiss(animated: true, completion: nil)
}
}
这是它运行的DataService函数(注意,我已经精简了该函数,因此并非所有变量都存在)
您可以通过加载数据来实现这一点,并在加载完成后推送新的VC设置下载的数据,但这不是一个好的UX方法,一个好的方法是在请求完成之前用加载指示器覆盖VC的视图,删除活动指示器并将数据设置为标签您需要将调用移动到观察侦听器中的闭包(处理程序)
observeSingleEvent
是异步的,这意味着它将立即返回,然后该行将执行handler(activityData)
,此时activityData
为空
func getActivityData(activityId: String, handler: (activities: [Activity]) -> Void )
{
var activityData = [Activity]()
REF_ACTIVITY.child(activityId).observeSingleEvent(of: .value)
{
(snapshot) in
guard let activity = snapshot.value as? NSDictionary else { return }
let activityId = activityId
let name = activity["name"] as? String ?? ""
let description = activity["description"] as? String ?? ""
let userId = activity["userId"] as? String ?? ""
let tempKillCount = activity["killCount"] as? NSNumber ?? 0
let killCount = Int(tempKillCount)
let tempSightingCount = activity["sightingCount"] as? NSNumber ?? 0
let sightingCount = Int(tempSightingCount)
let data = Activity(activityId: activityId, name: name, userId: userId, killCount: killCount, sightingCount: sightingCount)
activityData.append(data)
print("Within function - print activityData: ")
dump(activityData)
handler(activityData)
}
}
隐藏所有标签并添加活动指示器,直到数据加载,然后在加载时显示带有firebase数据的标签。如果对firebase的调用已超时,只需进行一次测试即可从数据库调用数据。从
dump(activityData)
@Ali获得的信息:activityData为空(-0个元素),那么如果activityData
为空,您希望如何显示数据<代码>活动数据为空表示您没有data@Ali这是一个很好的观点-我只是不明白为什么它是空的-如果我在函数中转储“activityData”,那么它会给出预期的数据。但如果我在ViewController中执行此操作,它将为空。在终端中,函数转储在ViewController中的转储之后写入。-基于此,我假设该函数是在viewControllernever认为处理程序(activityData)位于错误位置之后运行的。非常感谢你帮我做这件事。
func getActivityData(activityId: String, handler: (activities: [Activity]) -> Void )
{
var activityData = [Activity]()
REF_ACTIVITY.child(activityId).observeSingleEvent(of: .value)
{
(snapshot) in
guard let activity = snapshot.value as? NSDictionary else { return }
let activityId = activityId
let name = activity["name"] as? String ?? ""
let description = activity["description"] as? String ?? ""
let userId = activity["userId"] as? String ?? ""
let tempKillCount = activity["killCount"] as? NSNumber ?? 0
let killCount = Int(tempKillCount)
let tempSightingCount = activity["sightingCount"] as? NSNumber ?? 0
let sightingCount = Int(tempSightingCount)
let data = Activity(activityId: activityId, name: name, userId: userId, killCount: killCount, sightingCount: sightingCount)
activityData.append(data)
print("Within function - print activityData: ")
dump(activityData)
handler(activityData)
}
}