2017-02-17 12 views
0

У меня есть класс обслуживания для извлечения данных из моего Firebase:Swift класс обслуживания для извлечения данных Firebase

class Service { 
    var myName = String? 
    var myDev: String? 

    func getData() { 
     let databaseRef = FIRDatabase.database().reference() 
     databaseRef.child("Data").observeSingleEvent(of: .value, with: { (snapshot) in 
      let value = snapshot.value as? NSDictionary 
      let name = value?["name"] as? String ?? "" 
      self.myName = name 
      let dev = value?["dev"] as? String ?? "" 
      self.myDev = dev 
     }) { (error) in 
      print(error.localizedDescription) 
     } 
    } 
} 

и реализация в моем главном классе:

var service = Service() 

override func viewDidLoad(){ 
    super.viewDidLoad() 
    service.getData() 
    configureLabel() 
} 

private func configureLabel(){ 
    self.titleLabel.text = service.myName 
    self.devLabel.text = service.myDev 
} 

Проблема заключается в том: данные Firebase выбирается только после того, как мой ярлык получил значения myName и myDev. Таким образом, эти значения равны нулю.

ответ

0

Конечно, так оно и есть. Метод getData() делает асинхронный вызов службе Firebase. Смысл, метод firebase .observeSingleEvent работает в очереди async как большинство блоков кода, которые делают вызов службы. Таким образом, компилятор достигает линии getData(), подталкивает блок к другой очереди и продолжает компилировать следующие строки, которые находятся в исходной очереди. Если вы хотите, чтобы эти строки запускались после получения ответа, вы можете добавить закрытие метода getData() в качестве параметра.

Вы можете сделать что-то вроде этого:

getData(completion:() -> Void) { 
     let databaseRef = FIRDatabase.database().reference() 
     databaseRef.child("Data").observeSingleEvent(of: .value, with: { (snapshot) in 
      let value = snapshot.value as? NSDictionary 
      let name = value?["name"] as? String ?? "" 
      self.myName = name 
      let dev = value?["dev"] as? String ?? "" 
      self.myDev = dev 

      completion() 
     }) { (error) in 
      print(error.localizedDescription) 
     } 
    } 

    override func viewDidLoad(){ 
     super.viewDidLoad() 
     service.getData(completion: { Void in 
      configureLabel() 
     }) 

    } 
+0

Да, это помогло. Большое спасибо! –

0

это не лучшее решение, но оно должно решить вашу проблему.

struct MyStructure { 
     var name = "" 
     var dev = "" 

     init(with dictionary: [String: String]) { 
      if let name = dictionary["name"] { 
       self.name = name 
      } 
      if let dev = dictionary["dev"] { 
       self.dev = dev 
      } 
     } 
    } 

    class Service { 
     let databaseRef = FIRDatabase.database().reference() 

     func getData(completion: @escaping ((_ structure: MyStructure) -> Void)) { 
      databaseRef.child("Data").observeSingleEvent(of: .value, with: { snapshot in 
       if let value = snapshot.value as? [String: String] { 
        completion(MyStructure(with: value)) 
       } 
      }) { (error) in 
       print(error.localizedDescription) 
      } 
     } 
    } 

    let service = Service() 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     service.getData { myStructure in 
      DispatchQueue.main.async { 
       self.titleLabel.text = myStructure.name 
       self.devLabel.text = myStructure.dev      
      } 
     } 
    }