arrays - firestore - Recupera todos los valores de un secundario en Firebase con Swift iOS
firestore push to array (2)
Escribí una nueva clase y una nueva función de búsqueda. Vea cómo esto funciona para usted,
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
}
}
Función Fetch,
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
})
}
aquí está de acuerdo con tu código,
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
}
}
Estoy intentando recuperar todos los valores del secundario secundario de Firebase para mostrarlos en una etiqueta en la vista de colección. Tengo que obtener conexiones a una celda de vista de colección y tener un controlador de vista con una imagen y tres etiquetas. En la última etiqueta, quiero obtener todo el valor de precio de firebase child.
Estructura de Firebase
ViewController
Recuperando valores
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.
}
}
último error
Otra forma de la misma clase
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.
}
}
está obteniendo el error debajo ya que el valor no es una matriz del diccionario, el valor es una cadena.
if let cake = snapshot.value![a] as? [[String:String]]
debería ser
if let cake = snapshot.value![a] as? String
No veo el uso de fruitArray después de asignar la tasa de torta en fruitArray
Le sugiero que complete cakeArray como el siguiente código:
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()
Segundo error : no veo ningún objeto como clave en Cake struct. Entonces el compilador da error. Estás asignando valor en la línea anterior para cakeRateLabs
. Así que no hay necesidad de volver a asignar simplemente eliminar / comentar cell.cakeRateLabs.text = cakeArray[indexPath.item].key
.
Espero que esto solucione tu error y obtenga resultados como lo desees.