我非常确定我从Firebase获取数据的功能是否正常,但我无法在ViewController中显示数据。看起来View在函数完成之前呈现。
我需要帮助弄清楚如何在渲染视图之前运行该函数。
这是viewController
中的代码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函数(注意我已经缩减了函数,因此并非所有变量都存在)
// Get data on specific activity
func getActivityData(activityId: String, handler: @escaping (_ activities: [Activity]) -> ()) {
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)
}
答案 0 :(得分:1)
你需要将调用移动到observe侦听器
旁边的闭包(处理程序) 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)
}
}
答案 1 :(得分:0)
你可以通过加载数据实现这一点,一旦完成推送你的新VC设置了下载的数据,但这不是一个好的用户体验,一个好方法是用加载指示器覆盖VC的视图直到请求完成并删除活动指示器并将数据设置为标签