如何在ViewDidLoad之前完成功能

时间:2018-01-27 17:09:09

标签: ios swift firebase firebase-realtime-database uiviewcontroller

我非常确定我从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)
    }

2 个答案:

答案 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的视图直到请求完成并删除活动指示器并将数据设置为标签