【问题标题】:Retrieve all values from a sub child in Firebase with Swift iOS使用 Swift iOS 从 Firebase 中的子子项中检索所有值
【发布时间】:2017-07-13 22:21:43
【问题描述】:

我正在尝试从 Firebase 的子子项中检索所有值以显示在集合视图的标签中。 我必须获得到 Collection View Cell 的连接插座,并拥有一个具有图像和三个标签的 View 控制器。 在最后一个标签中,我想从 firebase child 中获取所有价格值。

Firebase 结构

视图控制器

检索值

  import UIKit
  import  Firebase
 class CakeViewController:  UIViewController , UICollectionViewDelegate,   UICollectionViewDataSource {

@IBOutlet weak var manuCake: UIBarButtonItem!

@IBOutlet weak var cakeCollectionView: UICollectionView!


struct cakeObject {

    var cakeImage : UIImage
    var cakeEnglichName: String
    var cakeUrduName : String
    var cakeRate : String
    var key : String



}

var cakeArray : [cakeObject] = []



override func viewDidLoad() {
    super.viewDidLoad()

    manuCake.target = revealViewController()
    manuCake.action = #selector(SWRevealViewController.revealToggle(_:))
    self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())



    let ref = FIRDatabase.database().reference().child("Hyderabad").child("Bakery").child("Cake")

    ref.observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.exists() {


            print(snapshot.value as Any)
            let cakeData = snapshot.value as! [String:String]
                for (key,value) in cakeData{
                    //Can set cakeImage and cakeUrduName as per your project
                    cakeArray.append(cakeObject(cakeImage: #imageLiteral(resourceName: "bakery_almond_cake"),cakeEnglinhName: key, cakeUrduName: "آلمنڑ کیک", cakeRate: "\(value)/kg"))
                }
                self.cakeCollectionView.reloadData()
            }

    })



    cakeCollectionView.delegate = self
    cakeCollectionView.dataSource = self

    // Do any additional setup after loading the view.
}





func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return cakeArray.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CakeCollectionViewCell", for: indexPath)
        as! CakeCollectionViewCell

    cell.cakeImageView.image = cakeArray[indexPath.item].cakeImage
    cell.cakeEngLabs.text = cakeArray[indexPath.item].cakeEnglichName
    cell.cakeUrLabs.text = cakeArray[indexPath.item].cakeUrduName
    cell.cakeRateLabs.text =  cakeArray[indexPath.item].key

    return cell

}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

最新错误

同类的另一种方式

 import UIKit
 import  Firebase
 class CakeViewController:  UIViewController , UICollectionViewDelegate,   UICollectionViewDataSource {

@IBOutlet weak var manuCake: UIBarButtonItem!

@IBOutlet weak var cakeCollectionView: UICollectionView!


struct cakeObject {

    var cakeImage : UIImage
    var cakeEnglichName: String
    var cakeUrduName : String
    //var cakeRate : String
    var key : String



}

var cakeArray : [cakeObject] = []



override func viewDidLoad() {
    super.viewDidLoad()

    manuCake.target = revealViewController()
    manuCake.action = #selector(SWRevealViewController.revealToggle(_:))
    self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())



    let ref = FIRDatabase.database().reference().child("Hyderabad").child("Bakery").child("Cake").child("Almond_Cake")

    ref.observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.exists() {


            print(snapshot.value as Any)
             let cakeData = snapshot.value as! [String:String]
                for (key,value) in cakeData{
                    //Can set cakeImage and cakeUrduName as per your project
                    self.cakeArray.append(cakeObject(cakeImage: #imageLiteral(resourceName: "bakery_almond_cake"),cakeEnglichName: key, cakeUrduName: "آلمنڑ کیک", key: "\(value)/kg"))
                }
                self.cakeCollectionView.reloadData()
            }
       })



    cakeCollectionView.delegate = self
    cakeCollectionView.dataSource = self

    // Do any additional setup after loading the view.
}





func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return cakeArray.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CakeCollectionViewCell", for: indexPath)
        as! CakeCollectionViewCell

    cell.cakeImageView.image = cakeArray[indexPath.item].cakeImage
    cell.cakeEngLabs.text = cakeArray[indexPath.item].cakeEnglichName
    cell.cakeUrLabs.text = cakeArray[indexPath.item].cakeUrduName
    cell.cakeRateLabs.text =  cakeArray[indexPath.item].key

    return cell

}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

另一种方式错误

【问题讨论】:

  • 您能否通过添加print(snapshot.value) 来简单地添加snapshot.value 的控制台日志。
  • io 应该在哪里做呢?
  • if snapshot.exists() { 行之后添加print(snapshot.value) 并在此处添加它的控制台日志。
  • 用警告更新问题
  • 我认为fruitArray[indexPath.item]["key"] 应该是fruitArray[indexPath.item].key 现在评论其他代码并运行应用程序,然后添加我要求的打印语句的控制台日志。

标签: arrays swift xcode firebase uicollectionview


【解决方案1】:

由于值不是字典数组,值是字符串,因此您遇到了错误。

if let cake = snapshot.value![a] as? [[String:String]]

应该是

if let cake = snapshot.value![a] as? String

fruitArray

中分配蛋糕率后,看不到 fruitArray 的使用

我建议你填写 cakeArray 如下代码:

print(snapshot.value as Any)
let cakeData = snapshot.value as! [String:String]
    for (key,value) in cakeData{
           //Can set cakeImage and cakeUrduName as per your project
           cakeArray.append(cakeObject(cakeImage: #imageLiteral(resourceName: "bakery_almond_cake"),cakeEnglinhName: key, cakeUrduName: "آلمنڑ کیک", cakeRate: "\(value)/kg"))                  
      }
    self.cakeCollectionView.reloadData()

第二个错误:我没有看到任何对象作为 cake struct 中的键。所以编译器给出错误。您在上一行中为 cakeRateLabs 赋值。所以无需再次分配,只需删除/评论cell.cakeRateLabs.text = cakeArray[indexPath.item].key

希望这一定会解决您的错误并获得您想要的输出。

【讨论】:

  • 非常感谢您的友好回复,但我收到一个错误 --- 使用未解决的标识符“a”---我已经更新了有问题的错误图片以及最新的问题代码
  • 写'key'而不是'a'我的错误我用'key'替换'a'。但忘了一处。将其设为 'snapshot.value![key]'
  • 谢谢亲爱的,但是[key] 'type 'any' has no subscript members'更新的错误图片和代码中仍然有错误
  • 在字典中获取快照值然后做进一步的操作。我更新了我的答案。
  • 感谢您的支持,但仍然出现错误,更新代码和错误图片请查看并帮助我完成此操作。
【解决方案2】:

我写了一个新的类和新的 fetch func。看看这对你有什么作用,

class CakeData {
   var cakeImage : UIImage?
   var cakeEnglichName: String?
   var cakeUrduName : String?
   //var cakeRate : String
    var key : String?
 init(postKey: String, postData: Dictionary <String, Any>) {
       self.key = postKey

       //Don't forget to add your keys
       if let cakeImage   = postData["addKey"] {
          self.cakeImage = cakeImage as? UIImage
       }
       if let cakeEnglichName = postData["addKey"] {
          self.cakeEnglichName = cakeEnglichName as? String
       }
       if let cakeUrduName = postData["addKey"] {
          self.cakeUrduName = cakeUrduName as? String
       }
     }

获取函数,

func fetchCakeData() {
    let ref = FIRDatabase.database().reference()
ref.child("Hyderabad").child("Bakery").child("Cake").observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
       if let cakeSnapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
           for cakes in cakeSnapshot {
               if let cakeDictionary = cakes.value as? Dictionary <String, Any> {
                   let key = cakes.key as String
                   //your class that takes a key as String and a Dictionary
                   let post = CakeData(postKey:key, postData: cakeDictionary)
                   self.cakeArray.append(post)
               }
           }
       }
      cakeCollectionView.delegate = self
     cakeCollectionView.dataSource = self
   })
}

这里是根据你的代码,

import UIKit
import Firebase

struct cakeObject {
    var cakeImage : UIImage
    var cakeEnglichName: String
    var cakeUrduName : String
    // var cakeRate : String
    var key : String
}
class CakeData {
    var cakeImage : UIImage?
    var cakeEnglichName: String?
    var cakeUrduName : String?
    //var cakeRate : String
    var key : String?
    init(postKey: String, postData: Dictionary <String, Any>) {
        self.key = postKey

        //Don't forget to add your keys
        if let cakeImage   = postData["addKey"] {
            self.cakeImage = cakeImage as? UIImage
        }
        if let cakeEnglichName = postData["addKey"] {
            self.cakeEnglichName = cakeEnglichName as? String
        }
        if let cakeUrduName = postData["addKey"] {
            self.cakeUrduName = cakeUrduName as? String
        }
    }
}


class CakeViewController: UIViewController , UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var manuCake: UIBarButtonItem!
    @IBOutlet weak var cakeCollectionView: UICollectionView!
    var cakeArray: [CakeData] = []
// var cakeArray : [cakeObject] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        manuCake.target = revealViewController()
        manuCake.action = #selector(SWRevealViewController.revealToggle(_:))
        self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        self.cakeCollectionView.delegate = self
        self.cakeCollectionView.dataSource = self
    }

    override func viewWillAppear(_ animated: Bool) {
        fetchCakeData()
    }

    func fetchCakeData() {
        let ref = FIRDatabase.database().reference()
        ref.child("Hyderabad").child("Bakery").child("Cake").observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
            if let cakeSnapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
                for cakes in cakeSnapshot {
                    if let cakeDictionary = cakes.value as? Dictionary <String, Any> {
                        let key = cakes.key as String
                        //your class that takes a key as String and a Dictionary
                        let post = CakeData(postKey:key, postData: cakeDictionary)
                        self.cakeArray.append(post)
                    }
                }
            }
            self.cakeCollectionView.reloadData()
        })
    }




 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cakeArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CakeCollectionViewCell", for: indexPath)
            as! CakeCollectionViewCell

        cell.cakeImageView.image = cakeArray[indexPath.item].cakeImage
        cell.cakeEngLabs.text = cakeArray[indexPath.item].cakeEnglichName
        cell.cakeUrLabs.text = cakeArray[indexPath.item].cakeUrduName
        cell.cakeRateLabs.text = cakeArray[indexPath.item].key



        print("Cake : \(cakeArray[indexPath.row])")
        cell.cakeImageView.image = cakeArray[indexPath.item].cakeImage
        cell.cakeEngLabs.text = cakeArray[indexPath.item].cakeEnglichName


        return cell 
    }


}

【讨论】:

  • 在“post”中发现错误:无法将 CakeData 类型的值转换为预期的参数类型 cakeviewcontroller.cakeObject
  • 你想发布完整的课程以及如何安排
  • 我不太明白你是怎么称呼它的,但请确保 cakeArray 是 CakeData [CakeData] 类型。
  • 请发布完整的课程我有重新安排的问题
  • 这就是我写的所有内容。您遇到什么错误?
猜你喜欢
  • 2019-07-18
  • 1970-01-01
  • 2017-12-20
  • 2019-05-09
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多