从Firebase读取到UIpickerView

时间:2018-01-30 22:22:56

标签: swift firebase uipickerview

我在执行以下操作时遇到了一些麻烦:

  1. 从Firebase数据库中读取。
  2. 将信息添加到我的UIpickerView中作为“选项”
  3. 在应用中显示“选项”。
  4. 我想要实现的目标是从“时间报告”中读取并在UIpickerView中显示“用户名”作为“选项”(在“下拉菜单中”)。

    (计划稍后可以在同一视图中显示每个“选项”中的信息。例如在应用中选择“用户”并显示用户“统计信息”。)

    任何帮助都会很棒!

    这是我的代码: 好吧,现在,我真的没有代码,因为我尝试的一切似乎都没有用。最后的工作代码是:

        func fetchUser()
    {
        ref = Database.database().reference() //Set the reference//
    
        databaseHandle = ref?.child("Time report").observe(.childAdded, with: { (snapshot) in
    
            print (snapshot)
        })
    }
    

    我的数据库看起来像:(登录是第一个节点。这意味着它的节点最接近根 - 如果这有任何感觉。) enter image description here enter image description here

    我的结果 嗯,就目前而言 - 我只收到Fred,Kalle和Ivar的所有信息......

    我试过了:

    • 将“childAdded”更改为Value。不要.. ..
    • 仅使用一个节点。意思是只有“Ivar”和几个随机值。在控制台中打印 - 但在挑选者视图中没有任何内容。

    使用此video来帮助创建一个pickerView。

3 个答案:

答案 0 :(得分:0)

你错过了基础知识,请阅读以下两篇文章: https://firebase.google.com/docs/database/ios/structure-data https://firebase.google.com/docs/database/ios/read-and-write

所以这是错误的:

  let ProjectInDatabase = snapshot.value as? String

举个例子,假设你想在" 2018-01-27 22:30:07 + 0000"

上收到亚当斯家的时间戳。
 databaseHandle = ref?.child(“Time report”).child(“Adam”).child(“Home”).child("2018-01-27 22:30:07 +0000”).observe(.childAdded, with: { (snapshot) in

  //you are getting back a dictionary with all the timestamp values i.e "From" : "2018-01-28 06:00:07 +0000", "To" : "2018-01-28 15:30:07 +0000"

    let ProjectInDatabase = snapshot.value as? Dictionary

     //now lets get the value of the “From” key

    let fromValue = ProjectInDatabase?["From"] as? String ?? ""

我不知道你的应用程序的细节,但值得考虑这个改变:

"Adam-Home":{
 "2018-01-27 22:30:07 +0000" : {
    "From" : "2018-01-28 06:00:07 +0000",
    "To" : "2018-01-28 15:30:07 +0000"
  }
 }
 "Adam-Work" : {
  "2018-01-26 22:30:07 +0000" : {
    "From" : "2018-01-28 06:00:07 +0000",
    "To" : "2018-01-28 15:30:07 +0000"
  }
}

以这样的方式构建数据库:每当您只回到所需内容时,就不再需要它了!

答案 1 :(得分:0)

以下是它的完成方式。我假设您知道如何为pickerView填充数据源。如果您需要帮助,最好将其作为一个单独的问题解决。

假设我们使用的结构类似于原始问题中的结构:

  time_report
    adam
      gym
        timestamp_0
          From : "from_0",
          To : "to_0"
        timestamp_1
          From : "from_1",
          To : "to_1"
      home : {
        timestamp_0
          From : "from_0",
          To : "to_0"
      work : {
        timestamp_0
          From : "from_0",
          To : "to_0"

注意:

1) best practice is to not use spaces in keys so I am using time_report
2) It's not clear if under each option (gym, home, work) there will be
      multiple nodes so I included two under gym for demonstration purposes
3) I am using placeholders for timestamps from_0, to_0 etc but you get the idea.
4) This will handle any situation for options; they could be gym, home, work
       or A, B, C or whatever the key names are.
5) Nothing is hard coded so as timestamps change, the code continues to work

现在阅读adam节点的选项(健身房,家庭,工作或其他任何内容),这里是代码。

let timeReportRef = self.ref.child("time_report")
let adamRef = timeReportRef.child("adam")
adamRef.observeSingleEvent(of: .value, with: { snapshot in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        let nodeKey = snap.key //will be gym, home, work
        print(nodeKey)
        //populate your dataSource Array here with the nodeKeys
        //the following code could be used to populate a structure with additional
        //  info so when the user taps 'gym', we have already loaded the gym data
        //   and can populate another view controller with the details
        for childTimes in snap.children { //the child nodes under gym, home, work
            let timeSnap = childTimes as! DataSnapshot
            let timeKey = timeSnap.key
            let dict = timeSnap.value as! [String: Any]
            let from = dict["From"] as! String
            let to = dict["To"] as! String

            print("  timestamp: \(timeKey)")
            print("     from: \(from)")
            print("       to: \(to)")
        }
    }
})

和输出

gym
  timestamp: timestamp_0
     from: from_0
       to: to_0
  timestamp: timestamp_1
     from: from_1
       to: to_1
home
  timestamp: timestamp_0
     from: from_0
       to: to_0
work
  timestamp: timestamp_0
     from: from_0
       to: to_0

这里重要的一点是,如果您只想将健身房,家庭,工作添加到pickerView,您可以省略For循环。然而。该循环演示了如何在健身房,家庭和工作中加载其他数据(时间戳)。

这里有几个方向。例如,如果您想在用户点击健身房时从Firebase加载firebase数据,您将获得用户点击的内容(健身房)并且您在adam部分中这样就可以

let user = userSection //assume we are in the 'adam' section
let option = optionTapped //assume the user tapped gym

let userOptionRef = self.ref.child(user).child(option)
userOptionRef.observeSingleEvent(.value.... etc etc to read in that data.

另一种选择是一次读取所有内容,如我提供的代码中所述),并用该信息填充一个类。然后将该类存储在dataSource数组中,以便在选择器中使用。

class userStuff {
   option = ""
   data: DataSnapshot?
}

在我提供的闭包中填充该类或stuct,然后将其存储在数组中。然后在pickerView中,当它被更新时,从行的数组中获取userStuff类并读取选项文本。如果用户然后点击第0行,'gym'读取数组,第0行,获取dataSnapshot并迭代它以使用时间戳信息填充子视图。

修改

原始问题已更改,并在此处发表评论:

let timeReportRef = self.ref.child("Time report")
timeReportRef.observeSingleEvent(of: .value, with: { snapshot in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        print(snap.key)
    }
})

输出

Fred
Ivar
Kalle

答案 2 :(得分:0)

我会做这样的事情。要获取他们的名字,您可以阅读snap的{​​{1}},然后获取他们的值,您也可以纠缠这些数据。

key