函数没有返回,Swift Firebase

Posted

技术标签:

【中文标题】函数没有返回,Swift Firebase【英文标题】:Function isn't returning, Swift Firebase 【发布时间】:2017-10-06 05:35:03 【问题描述】:

我正在尝试使用下面显示的方法从 firebase 中提取数据并放入一个数组中。当使用建议的错误完成处理程序时,我将 Data 的值分配给数组 locData。 get locdata函数一直在最底层。

import UIKit
import Firebase
class SearchSelectVC: UIViewController, UIPickerViewDelegate , UIPickerViewDataSource

    @IBOutlet weak var locationPicker: UIPickerView!
    @IBOutlet weak var humidityPicker: UIPickerView!
    @IBOutlet weak var datePicker: UIPickerView!
    @IBOutlet weak var locationLB: UILabel!
    @IBOutlet weak var humidityLB: UILabel!
    @IBOutlet weak var dateLB: UILabel!

    var locData: [String] = [String]()
    var humidityData : [String] = [String]()
    var dateData : [String] = [String]()

    override func viewDidLoad() 
        super.viewDidLoad()
        //  initPickers()
        humidityPicker.delegate = self
        humidityPicker.dataSource = self
        locationPicker.delegate = self
        locationPicker.dataSource = self
        datePicker.delegate = self
        datePicker.dataSource = self
        //locData = [ "hi" , "hi2 ","hi3","hi4", "hi5", "hi6", "hi7"]
        //dateData = [ "no" , "no2 ","no3","no4", "no5", "no6", "no7"]
        //humidityData = [ "yes" , "yes2 ","yes3","yes4", "yes5", "yes6", "yes7"]
        //datePicker.isHidden = true
        //locationPicker.isHidden = true
        //humidityPicker.isHidden = true
        getLoc(onCompletion:  (data) in
            print(data)
            self.locData = data
        , onError:  (error) in
        )
        print(locData)
    

    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        if(pickerView == locationPicker)
            return 1
        
        else if(pickerView == datePicker)
            return 1
        
        else if(pickerView == humidityPicker)
            return 1
        
        return 1
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        if (pickerView == locationPicker) 
            return locData.count
        
        else if (pickerView == humidityPicker)
            return humidityData.count
        
        else if (pickerView == datePicker) 
            return dateData.count
        
        return 1
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if (pickerView == locationPicker) 
            return locData[row]
        
        else if(pickerView == datePicker)
            return dateData[row]
        
        if(pickerView == humidityPicker)
            return humidityData[row]
        
        return "thisisbad"
    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
    
        if(pickerView == locationPicker)
            updateLabelLoc()
            getDate(onCompletion:  (data) in
                print(data)
                self.dateData = data
            , onError:  (error) in
            )
        
        else if(pickerView == datePicker)
            updateLabelDate()
            getHumidity(onCompletion:  (data) in
                print(data)
                self.humidityData = data
            , onError:  (error) in
            )
        
        else if(pickerView == humidityPicker)
            updateLabelHumidity()
        
    
    func updateLabelLoc()
        let location = locData[locationPicker.selectedRow(inComponent: 0)]
        locationLB.text = location
    
    func updateLabelDate()
        let date = dateData[datePicker.selectedRow(inComponent: 0)]
        dateLB.text = date
    
    func updateLabelHumidity()
        let humidity = humidityData[datePicker.selectedRow(inComponent: 0)]
        humidityLB.text = humidity
    
    func getDate(onCompletion: @escaping (Array<String>) -> Void, onError: @escaping (NSError) -> Void) 
        var data : [String] = []
        let selectedLoc = locationLB.text
        var dateRef: DatabaseReference!
        dateRef = Database.database().reference().child("launch").child((selectedLoc)!)
        dateRef.observeSingleEvent(of: .value, with:  (snapshot) in
            for child in snapshot.children 
                let snap = child as! DataSnapshot
                let key = snap.key
                data.append(key)
                print("date = \(key)")
                print(data)
                onCompletion(data)
            
        )
    
    func getLoc(onCompletion: @escaping (Array<String>) -> Void, onError: @escaping (NSError) -> Void)
        var data : [String] = []
        var locRef: DatabaseReference!
        locRef = Database.database().reference().child("launch")
        locRef.observeSingleEvent(of: .value, with:  (snapshot) in
            for child in snapshot.children 
                let snap = child as! DataSnapshot
                let key = snap.key
                data.append(key)
                print("location = \(key)")
                print(data)
                onCompletion(data)
            

        )
    
    func getHumidity(onCompletion: @escaping (Array<String>) -> Void, onError: @escaping (NSError) -> Void)
        var data : [String] = []
        let selectedLoc = locationLB.text
        let selectedDate = dateLB.text
        var humidityRef: DatabaseReference!
        humidityRef = Database.database().reference().child("launch").child((selectedLoc)!).child((selectedDate)!)
        humidityRef.observeSingleEvent(of: .value, with:  (snapshot) in
            for child in snapshot.children 
                let snap = child as! DataSnapshot
                let key = snap.key
                data.append(key)
                print("humidity = \(key)")
                print(data)
                onCompletion(data)
            
        )
    
    func initPicker(onCompletion: @escaping (Array<String>) -> Void, onError: @escaping (NSError) -> Void)
        humidityPicker.delegate = self
        humidityPicker.dataSource = self
        locationPicker.delegate = self
        locationPicker.dataSource = self
        datePicker.delegate = self
        datePicker.dataSource = self
    

我不确定我是否正确分配了它,但是当我尝试打印 locData 时,没有任何反应。另外,当我运行程序时,我的 UIPickerViews 没有显示出来。

【问题讨论】:

您应该使用完成处理程序而不是返回数组。您当前正在返回之前的数据,甚至在附加任何数据之前。 【参考方案1】:

observeSingleEvent 是一个异步调用,因此您需要在函数 getDate 上创建一个 completionHandler,该函数将在方法完成时调用:

func getDate(onCompletion: @escaping ([String]) -> Void) 
    var data : [String] = []
    let selectedLoc = locationLB.text
    var dateRef: DatabaseReference!
    dateRef = Database.database().reference().child("launch").child((selectedLoc)!)
    dateRef.observeSingleEvent(of: .value, with:  (snapshot) in
        for child in snapshot.children 
            let snap = child as! DataSnapshot
            let key = snap.key
            data.append(key)
            print("date = \(key)")
            print(data)
            onCompletion(data)
        
    )

称呼它:

getDate(onCompletion:  (data) in
    print(data)

【讨论】:

@RohanRao,阅读有关该调用的信息,我认为您不需要错误部分,因此我将其删除。也可以使用return [String] 而不是您的completionHandler 来接受和回答,然后删除接受并更新问题。你应该问一个新问题。 @RohanRao,你可能每天有 1 个问题 是的,我想是的。 当我调用该函数并想将它添加到我的数组中时,我会执行 myArray.append(date) 之类的操作吗? 我不知道结构,但您应该将字符串日期附加到您的数组中。

以上是关于函数没有返回,Swift Firebase的主要内容,如果未能解决你的问题,请参考以下文章

函数返回数组没有在 for 循环 Swift 中获得追加

放入函数时,工作 Swift 代码返回“表达式类型不明确,没有更多上下文”

Swift 2 - 使用 Alamofire 时函数不返回 Bool

函数作为swift4中的类型

Swift基础语法

关于swift中函数的定义